22 using namespace UCOMMON_NAMESPACE;
24 static const char *delfile = NULL;
25 static shell::flagopt helpflag(
'h',
"--help", _TEXT(
"display this list"));
26 static shell::flagopt althelp(
'?', NULL, NULL);
27 static shell::stringopt configdir(
'C',
"--config", _TEXT(
"config directory"),
"path", NULL);
28 static shell::stringopt encoding(
'e',
"--encoding", _TEXT(
"audio format"),
"type",
"pcmu");
29 static shell::numericopt framing(
'f',
"--framing", _TEXT(
"audio framing"),
"msec", 20);
30 static shell::numericopt interdigit(
'i',
"--interdigit", _TEXT(
"interdigit timing"),
"msec", 60);
31 static shell::numericopt level(
'l',
"--level", _TEXT(
"audio level"),
"level", 30000);
32 static shell::numericopt maxtime(
'm',
"--max", _TEXT(
"max time"),
"msec", 60000);
33 static shell::numericopt offset(
's',
"--offset", _TEXT(
"offset into stream"),
"msec", 0);
34 static shell::stringopt lang(
'L',
"--lang", _TEXT(
"specify language"),
"language",
"C");
35 static shell::stringopt prefix(
'P',
"--prefix", _TEXT(
"specify alternate prefix path"),
"path", NULL);
36 static shell::stringopt suffix(
'S',
"--suffix", _TEXT(
"audio extension"),
".ext",
".au");
37 static shell::stringopt voice(
'V',
"--voice", _TEXT(
"specify voice library"),
"name",
"default");
38 static shell::stringopt phrasebook(
'B',
"--phrasebook", _TEXT(
"specify phrasebook directory"),
"path", NULL);
39 static Env::pathinfo_t ruleset;
41 static Tonegen *getTone(
char **argv, Audio::level_t l, timeout_t framing, timeout_t interdigit)
46 if(!stricmp(*argv,
"dtmf"))
47 return new DTMFDialer(*(++argv), l, framing, interdigit);
48 else if(!stricmp(*argv,
"mf"))
49 return new MFDialer(*(++argv), l, framing, interdigit);
53 key = Tonegen::find(name, locale);
57 return new Tonegen(key, l, framing);
60 static const char *fname(
const char *cp)
62 const char *fn = strrchr(cp,
'/');
64 fn = strrchr(cp,
'\\');
74 Audio::info_t info, make;
77 Audio::linear_t buffer;
78 char *filename = (
char *)
"tones.conf";
81 Tonegen::load(filename);
87 shell::errexit(3,
"*** tonetool: %s\n",
88 _TEXT(
"no tone spec to use"));
92 make.encoding = Audio::getEncoding(*encoding);
94 ruleset.voices = *voice;
96 if(!Env::path(ruleset, target, pathbuf,
sizeof(pathbuf),
true))
97 shell::errexit(3,
"*** tonetool: %s: %s\n",
98 target, _TEXT(
"invalid destination"));
102 make.rate = Audio::rate8khz;
106 output.create(target, make, *framing);
109 output.open(target, Audio::modeWrite, *framing);
111 output.setPosition(*offset);
113 output.setPosition();
116 if(!output.is_open()) {
117 shell::errexit(3,
"*** tonetool: %s: %s\n",
118 fname(target), _TEXT(
"cannot access"));
121 if(!output.is_streamable()) {
122 shell::errexit(4,
"*** tonetool: %s: %s\n",
123 fname(target), _TEXT(
"unable to load codec"));
126 output.getInfo(info);
128 tone = getTone(argv, ((Audio::level_t)*level), info.framing, *interdigit);
131 shell::errexit(5,
"*** tonetool: %s\n",
132 _TEXT(
"unrecognized tone spec used"));
135 printf(
"%s: ", fname(target));
136 maxframes = *maxtime / info.framing;
139 buffer = tone->getFrame();
141 if(tone->is_complete())
146 output.putMono(buffer);
147 if(tone->is_silent())
159 const char *locale = NULL;
167 if(eq(
"--", option)) {
172 if(eq(
"--", option, 2))
175 if(eq(option,
"-locale=", 8)) {
181 if(eq(option,
"-locale")) {
184 shell::errexit(2,
"*** tonetool: -locale: %s\n",
185 _TEXT(
"missing argument"));
194 if(*argv && **argv ==
'-') {
195 shell::errexit(1,
"*** tonetool: %s: %s\n",
196 *argv, _TEXT(
"unknown option"));
200 shell::errexit(3,
"*** tonetool: %s\n",
201 _TEXT(
"tone name missing"));
204 if(!Tonegen::load(locale)) {
205 shell::errexit(4,
"*** tonetool: %s\n",
206 _TEXT(
"unable to load"));
210 printf(
"%s:", *argv);
211 key = Tonegen::find(*(argv++), locale);
213 printf(
" %s\n", _TEXT(
"not found"));
220 if(def->f2 && def->f1)
221 printf(
"%d+%d", def->f1, def->f2);
223 printf(
"%d", def->f1);
226 printf(
" %ldms\n", def->duration);
228 printf(
" forever\n");
233 printf(
" silence %ldms\n", def->silence);
235 if(def == key->last) {
236 if(def->next == key->first)
237 printf(
" repeat full\n");
239 printf(
" repeat partial\n");
252 Audio::Info info, make;
254 Audio::linear_t buffer;
258 ruleset.voices = *voice;
263 if(!Env::path(ruleset, target, pathbuf,
sizeof(pathbuf)))
264 shell::errexit(3,
"*** tonetool: %s: %s\n",
265 target, _TEXT(
"invalid destination"));
269 input.open(target, Audio::modeRead, *framing);
271 if(!input.is_open()) {
272 shell::errexit(3,
"*** tonetool: %s: %s\n",
273 fname(target), _TEXT(
"cannot access"));
276 if(!input.is_streamable()) {
277 shell::errexit(4,
"*** tonetool: %s: %s\n",
278 fname(target), _TEXT(
"unable to load codec"));
282 dtmf =
new DTMFDetect;
284 buffer =
new Audio::sample_t[input.getCount()];
287 if(!input.getMono(buffer, 1))
290 dtmf->putSamples(buffer, input.getCount());
293 dtmf->getResult(result,
sizeof(result));
294 printf(
"%s: %s\n", fname(target), result);
303 static void stop(
void)
313 shell::bind(
"tonetool");
314 shell args(argc, argv);
319 Env::set(
"prefix", *prefix);
322 Env::set(
"voices", *phrasebook);
325 Env::set(
"extension", *suffix);
328 Env::set(
"config", *configdir);
331 ruleset.book = Phrasebook::find(*lang);
333 ruleset.book = Phrasebook::find(NULL);
335 if(is(helpflag) || is(althelp)) {
336 printf(
"%s\n", _TEXT(
"Usage: tonetool [options] command [arguments...]"));
337 printf(
"%s\n\n", _TEXT(
"Tone tool operations"));
338 printf(
"%s\n", _TEXT(
"Options:"));
340 printf(
"\n%s\n", _TEXT(
"Report bugs to dyfet@gnu.org"));
345 shell::errexit(1,
"*** tonetool: %s\n",
346 _TEXT(
"no command specified"));
348 const char *cp = args[0];
353 shell::exiting(stop);
357 else if(eq(cp,
"detect"))
359 else if(eq(cp,
"create"))
361 else if(eq(cp,
"append"))
364 shell::errexit(1,
"*** tonetool: %s: %s\n",
365 cp, _TEXT(
"unknown option"));
#define BAYONNE_NAMESPACE
GNU Bayonne library namespace.