1 /*
2 * Copyright (C) 2010 DSD Author
3 * GPG Key ID: 0x3F1D7FD0 (74EF 430D F7F2 0A48 FCE6 F630 FAA2 635D 3F1D 7FD0)
4 *
5 * Permission to use, copy, modify, and/or distribute this software for any
6 * purpose with or without fee is hereby granted, provided that the above
7 * copyright notice and this permission notice appear in all copies.
8 *
9 * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
10 * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
11 * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
12 * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
13 * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
14 * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
15 * PERFORMANCE OF THIS SOFTWARE.
16 */
17
18 #define _MAIN
19
20 #include "dsd.h"
21 #include "p25p1_const.h"
22 #include "x2tdma_const.h"
23 #include "dstar_const.h"
24 #include "nxdn_const.h"
25 #include "dmr_const.h"
26 #include "provoice_const.h"
27
28 int exitflag;
29
30 int
comp(const void * a,const void * b)31 comp (const void *a, const void *b)
32 {
33 if (*((const int *) a) == *((const int *) b))
34 return 0;
35 else if (*((const int *) a) < *((const int *) b))
36 return -1;
37 else
38 return 1;
39 }
40
41 void
noCarrier(dsd_opts * opts,dsd_state * state)42 noCarrier (dsd_opts * opts, dsd_state * state)
43 {
44 state->dibit_buf_p = state->dibit_buf + 200;
45 memset (state->dibit_buf, 0, sizeof (int) * 200);
46 if (opts->mbe_out_f != NULL)
47 {
48 closeMbeOutFile (opts, state);
49 }
50 state->jitter = -1;
51 state->lastsynctype = -1;
52 state->carrier = 0;
53 state->max = 15000;
54 state->min = -15000;
55 state->center = 0;
56 state->err_str[0] = 0;
57 sprintf (state->fsubtype, " ");
58 sprintf (state->ftype, " ");
59 state->errs = 0;
60 state->errs2 = 0;
61 state->lasttg = 0;
62 state->lastsrc = 0;
63 state->lastp25type = 0;
64 state->repeat = 0;
65 state->nac = 0;
66 state->numtdulc = 0;
67 sprintf (state->slot0light, " slot0 ");
68 sprintf (state->slot1light, " slot1 ");
69 state->firstframe = 0;
70 if (opts->audio_gain == (float) 0)
71 {
72 state->aout_gain = 25;
73 }
74 memset (state->aout_max_buf, 0, sizeof (float) * 200);
75 state->aout_max_buf_p = state->aout_max_buf;
76 state->aout_max_buf_idx = 0;
77 sprintf (state->algid, "________");
78 sprintf (state->keyid, "________________");
79 mbe_initMbeParms (state->cur_mp, state->prev_mp, state->prev_mp_enhanced);
80 }
81
82 void
initOpts(dsd_opts * opts)83 initOpts (dsd_opts * opts)
84 {
85
86 opts->onesymbol = 10;
87 opts->mbe_in_file[0] = 0;
88 opts->mbe_in_f = NULL;
89 opts->errorbars = 1;
90 opts->datascope = 0;
91 opts->symboltiming = 0;
92 opts->verbose = 2;
93 opts->p25enc = 0;
94 opts->p25lc = 0;
95 opts->p25status = 0;
96 opts->p25tg = 0;
97 opts->scoperate = 15;
98 sprintf (opts->audio_in_dev, "/dev/audio");
99 opts->audio_in_fd = -1;
100 sprintf (opts->audio_out_dev, "/dev/audio");
101 opts->audio_out_fd = -1;
102 opts->split = 0;
103 opts->playoffset = 0;
104 opts->mbe_out_dir[0] = 0;
105 opts->mbe_out_file[0] = 0;
106 opts->mbe_out_f = NULL;
107 opts->audio_gain = 0;
108 opts->audio_out = 1;
109 opts->wav_out_file[0] = 0;
110 opts->wav_out_f = NULL;
111 opts->wav_out_fd = -1;
112 opts->serial_baud = 115200;
113 sprintf (opts->serial_dev, "/dev/ttyUSB0");
114 opts->resume = 0;
115 opts->frame_dstar = 0;
116 opts->frame_x2tdma = 1;
117 opts->frame_p25p1 = 1;
118 opts->frame_nxdn48 = 0;
119 opts->frame_nxdn96 = 1;
120 opts->frame_dmr = 1;
121 opts->frame_provoice = 0;
122 opts->mod_c4fm = 1;
123 opts->mod_qpsk = 1;
124 opts->mod_gfsk = 1;
125 opts->uvquality = 3;
126 opts->inverted_x2tdma = 1; // most transmitter + scanner + sound card combinations show inverted signals for this
127 opts->inverted_dmr = 0; // most transmitter + scanner + sound card combinations show non-inverted signals for this
128 opts->mod_threshold = 26;
129 opts->ssize = 36;
130 opts->msize = 15;
131 opts->playfiles = 0;
132 opts->delay = 0;
133 }
134
135 void
initState(dsd_state * state)136 initState (dsd_state * state)
137 {
138
139 int i, j;
140
141 state->dibit_buf = malloc (sizeof (int) * 1000000);
142 state->dibit_buf_p = state->dibit_buf + 200;
143 memset (state->dibit_buf, 0, sizeof (int) * 200);
144 state->repeat = 0;
145 state->audio_out_buf = malloc (sizeof (short) * 1000000);
146 memset (state->audio_out_buf, 0, 100 * sizeof (short));
147 state->audio_out_buf_p = state->audio_out_buf + 100;
148 state->audio_out_float_buf = malloc (sizeof (float) * 1000000);
149 memset (state->audio_out_float_buf, 0, 100 * sizeof (float));
150 state->audio_out_float_buf_p = state->audio_out_float_buf + 100;
151 state->audio_out_idx = 0;
152 state->audio_out_idx2 = 0;
153 state->audio_out_temp_buf_p = state->audio_out_temp_buf;
154 state->wav_out_bytes = 0;
155 state->center = 0;
156 state->jitter = -1;
157 state->synctype = -1;
158 state->min = -15000;
159 state->max = 15000;
160 state->lmid = 0;
161 state->umid = 0;
162 state->minref = -12000;
163 state->maxref = 12000;
164 state->lastsample = 0;
165 for (i = 0; i < 128; i++)
166 {
167 state->sbuf[i] = 0;
168 }
169 state->sidx = 0;
170 for (i = 0; i < 1024; i++)
171 {
172 state->maxbuf[i] = 15000;
173 }
174 for (i = 0; i < 1024; i++)
175 {
176 state->minbuf[i] = -15000;
177 }
178 state->midx = 0;
179 state->err_str[0] = 0;
180 sprintf (state->fsubtype, " ");
181 sprintf (state->ftype, " ");
182 state->symbolcnt = 0;
183 state->rf_mod = 0;
184 state->numflips = 0;
185 state->lastsynctype = -1;
186 state->lastp25type = 0;
187 state->offset = 0;
188 state->carrier = 0;
189 for (i = 0; i < 25; i++)
190 {
191 for (j = 0; j < 16; j++)
192 {
193 state->tg[i][j] = 48;
194 }
195 }
196 state->tgcount = 0;
197 state->lasttg = 0;
198 state->lastsrc = 0;
199 state->nac = 0;
200 state->errs = 0;
201 state->errs2 = 0;
202 state->mbe_file_type = -1;
203 state->optind = 0;
204 state->numtdulc = 0;
205 state->firstframe = 0;
206 sprintf (state->slot0light, " slot0 ");
207 sprintf (state->slot1light, " slot1 ");
208 state->aout_gain = 25;
209 memset (state->aout_max_buf, 0, sizeof (float) * 200);
210 state->aout_max_buf_p = state->aout_max_buf;
211 state->aout_max_buf_idx = 0;
212 state->samplesPerSymbol = 10;
213 state->symbolCenter = 4;
214 sprintf (state->algid, "________");
215 sprintf (state->keyid, "________________");
216 state->currentslot = 0;
217 state->cur_mp = malloc (sizeof (mbe_parms));
218 state->prev_mp = malloc (sizeof (mbe_parms));
219 state->prev_mp_enhanced = malloc (sizeof (mbe_parms));
220 mbe_initMbeParms (state->cur_mp, state->prev_mp, state->prev_mp_enhanced);
221 state->p25kid = 0;
222 }
223
224 void
usage()225 usage ()
226 {
227 printf ("\n");
228 printf ("Usage:\n");
229 printf (" dsd [options] Live scanner mode\n");
230 printf (" dsd [options] -r <files> Read/Play saved mbe data from file(s)\n");
231 printf (" dsd -h Show help\n");
232 printf ("\n");
233 printf ("Display Options:\n");
234 printf (" -e Show Frame Info and errorbars (default)\n");
235 printf (" -pe Show P25 encryption sync bits\n");
236 printf (" -pl Show P25 link control bits\n");
237 printf (" -ps Show P25 status bits and low speed data\n");
238 printf (" -pt Show P25 talkgroup info\n");
239 printf (" -q Don't show Frame Info/errorbars\n");
240 printf (" -s Datascope (disables other display options)\n");
241 printf (" -t Show symbol timing during sync\n");
242 printf (" -v <num> Frame information Verbosity\n");
243 printf (" -z <num> Frame rate for datascope\n");
244 printf ("\n");
245 printf ("Input/Output options:\n");
246 printf (" -i <device> Audio input device (default is /dev/audio)\n");
247 printf (" -o <device> Audio output device (default is /dev/audio)\n");
248 printf (" -d <dir> Create mbe data files, use this directory\n");
249 printf (" -g <num> Audio output gain (default = 0 = auto)\n");
250 printf (" -n Do not send synthesized speech to audio output device\n");
251 printf (" -w <file> Output synthesized speech to a .wav file\n");
252 printf ("\n");
253 printf ("Scanner control options:\n");
254 printf (" -B <num> Serial port baud rate (default=115200)\n");
255 printf (" -C <device> Serial port for scanner control (default=/dev/ttyUSB0)\n");
256 printf (" -R <num> Resume scan after <num> TDULC frames or any PDU or TSDU\n");
257 printf ("\n");
258 printf ("Decoder options:\n");
259 printf (" -fa Auto-detect frame type (default)\n");
260 printf (" -f1 Decode only P25 Phase 1\n");
261 printf (" -fd Decode only D-STAR* (no audio)\n");
262 printf (" -fi Decode only NXDN48* (6.25 kHz) / IDAS*\n");
263 printf (" -fn Decode only NXDN96 (12.5 kHz)\n");
264 printf (" -fp Decode only ProVoice*\n");
265 printf (" -fr Decode only DMR/MOTOTRBO\n");
266 printf (" -fx Decode only X2-TDMA\n");
267 printf (" -ma Auto-select modulation optimizations (default)\n");
268 printf (" -mc Use only C4FM modulation optimizations\n");
269 printf (" -mg Use only GFSK modulation optimizations\n");
270 printf (" -mq Use only QPSK modulation optimizations\n");
271 printf (" -u <num> Unvoiced speech quality (default=3)\n");
272 printf (" -xx Expect non-inverted X2-TDMA signal\n");
273 printf (" -xr Expect inverted DMR/MOTOTRBO signal\n");
274 printf ("\n");
275 printf (" * denotes frame types that cannot be auto-detected.\n");
276 printf ("\n");
277 printf ("Advanced decoder options:\n");
278 printf (" -A <num> QPSK modulation auto detection threshold (default=26)\n");
279 printf (" -S <num> Symbol buffer size for QPSK decision point tracking\n");
280 printf (" (default=36)\n");
281 printf (" -M <num> Min/Max buffer size for QPSK decision point tracking\n");
282 printf (" (default=15)\n");
283 exit (0);
284 }
285
286 void
liveScanner(dsd_opts * opts,dsd_state * state)287 liveScanner (dsd_opts * opts, dsd_state * state)
288 {
289 while (1)
290 {
291 noCarrier (opts, state);
292 state->synctype = getFrameSync (opts, state);
293 // recalibrate center/umid/lmid
294 state->center = ((state->max) + (state->min)) / 2;
295 state->umid = (((state->max) - state->center) * 5 / 8) + state->center;
296 state->lmid = (((state->min) - state->center) * 5 / 8) + state->center;
297 while (state->synctype != -1)
298 {
299 processFrame (opts, state);
300 state->synctype = getFrameSync (opts, state);
301 // recalibrate center/umid/lmid
302 state->center = ((state->max) + (state->min)) / 2;
303 state->umid = (((state->max) - state->center) * 5 / 8) + state->center;
304 state->lmid = (((state->min) - state->center) * 5 / 8) + state->center;
305 }
306 }
307 }
308
309 void
cleanupAndExit(dsd_opts * opts,dsd_state * state)310 cleanupAndExit (dsd_opts * opts, dsd_state * state)
311 {
312 noCarrier (opts, state);
313 if (opts->wav_out_f != NULL)
314 {
315 closeWavOutFile (opts, state);
316 }
317 printf ("Exiting.\n");
318 exit (0);
319 }
320
321 void
sigfun(int sig)322 sigfun (int sig)
323 {
324 exitflag = 1;
325 signal (SIGINT, SIG_DFL);
326 }
327
328 int
main(int argc,char ** argv)329 main (int argc, char **argv)
330 {
331
332 int c;
333 extern char *optarg;
334 extern int optind, opterr, optopt;
335 dsd_opts opts;
336 dsd_state state;
337 char versionstr[25];
338 mbe_printVersion (versionstr);
339
340 printf ("Digital Speech Decoder 1.6.0\n");
341 printf ("mbelib version %s\n", versionstr);
342
343 initOpts (&opts);
344 initState (&state);
345
346 exitflag = 0;
347 signal (SIGINT, sigfun);
348
349 while ((c = getopt (argc, argv, "hep:qstv:z:i:o:d:g:nw:B:C:R:f:m:u:x:A:S:M:r")) != -1)
350 {
351 opterr = 0;
352 switch (c)
353 {
354 case 'h':
355 usage ();
356 exit (0);
357 case 'e':
358 opts.errorbars = 1;
359 opts.datascope = 0;
360 break;
361 case 'p':
362 if (optarg[0] == 'e')
363 {
364 opts.p25enc = 1;
365 }
366 else if (optarg[0] == 'l')
367 {
368 opts.p25lc = 1;
369 }
370 else if (optarg[0] == 's')
371 {
372 opts.p25status = 1;
373 }
374 else if (optarg[0] == 't')
375 {
376 opts.p25tg = 1;
377 }
378 break;
379 case 'q':
380 opts.errorbars = 0;
381 opts.verbose = 0;
382 break;
383 case 's':
384 opts.errorbars = 0;
385 opts.p25enc = 0;
386 opts.p25lc = 0;
387 opts.p25status = 0;
388 opts.p25tg = 0;
389 opts.datascope = 1;
390 opts.symboltiming = 0;
391 break;
392 case 't':
393 opts.symboltiming = 1;
394 opts.errorbars = 1;
395 opts.datascope = 0;
396 break;
397 case 'v':
398 sscanf (optarg, "%d", &opts.verbose);
399 break;
400 case 'z':
401 sscanf (optarg, "%d", &opts.scoperate);
402 opts.errorbars = 0;
403 opts.p25enc = 0;
404 opts.p25lc = 0;
405 opts.p25status = 0;
406 opts.p25tg = 0;
407 opts.datascope = 1;
408 opts.symboltiming = 0;
409 printf ("Setting datascope frame rate to %i frame per second.\n", opts.scoperate);
410 break;
411 case 'i':
412 sscanf (optarg, "%s", opts.audio_in_dev);
413 break;
414 case 'o':
415 sscanf (optarg, "%s", opts.audio_out_dev);
416 break;
417 case 'd':
418 sscanf (optarg, "%s", opts.mbe_out_dir);
419 printf ("Writing mbe data files to directory %s\n", opts.mbe_out_dir);
420 break;
421 case 'g':
422 sscanf (optarg, "%f", &opts.audio_gain);
423 if (opts.audio_gain <= (float) 0)
424 {
425 opts.audio_gain = (float) 0;
426 printf ("Enabling audio out auto-gain\n");
427 }
428 else
429 {
430 printf ("Setting audio out gain to %f\n", opts.audio_gain);
431 state.aout_gain = opts.audio_gain;
432 }
433 break;
434 case 'n':
435 opts.audio_out = 0;
436 printf ("Disabling audio output to soundcard.\n");
437 break;
438 case 'w':
439 sscanf (optarg, "%s", opts.wav_out_file);
440 printf ("Writing audio to file %s\n", opts.wav_out_file);
441 openWavOutFile (&opts, &state);
442 break;
443 case 'B':
444 sscanf (optarg, "%d", &opts.serial_baud);
445 break;
446 case 'C':
447 sscanf (optarg, "%s", opts.serial_dev);
448 break;
449 case 'R':
450 sscanf (optarg, "%d", &opts.resume);
451 printf ("Enabling scan resume after %i TDULC frames\n", opts.resume);
452 break;
453 case 'f':
454 if (optarg[0] == 'a')
455 {
456 opts.frame_dstar = 0;
457 opts.frame_x2tdma = 1;
458 opts.frame_p25p1 = 1;
459 opts.frame_nxdn48 = 0;
460 opts.frame_nxdn96 = 1;
461 opts.frame_dmr = 1;
462 opts.frame_provoice = 0;
463 }
464 else if (optarg[0] == 'd')
465 {
466 opts.frame_dstar = 1;
467 opts.frame_x2tdma = 0;
468 opts.frame_p25p1 = 0;
469 opts.frame_nxdn48 = 0;
470 opts.frame_nxdn96 = 0;
471 opts.frame_dmr = 0;
472 opts.frame_provoice = 0;
473 printf ("Decoding only D-STAR frames.\n");
474 }
475 else if (optarg[0] == 'x')
476 {
477 opts.frame_dstar = 0;
478 opts.frame_x2tdma = 1;
479 opts.frame_p25p1 = 0;
480 opts.frame_nxdn48 = 0;
481 opts.frame_nxdn96 = 0;
482 opts.frame_dmr = 0;
483 opts.frame_provoice = 0;
484 printf ("Decoding only X2-TDMA frames.\n");
485 }
486 else if (optarg[0] == 'p')
487 {
488 opts.frame_dstar = 0;
489 opts.frame_x2tdma = 0;
490 opts.frame_p25p1 = 0;
491 opts.frame_nxdn48 = 0;
492 opts.frame_nxdn96 = 0;
493 opts.frame_dmr = 0;
494 opts.frame_provoice = 1;
495 state.samplesPerSymbol = 5;
496 state.symbolCenter = 2;
497 opts.mod_c4fm = 0;
498 opts.mod_qpsk = 0;
499 opts.mod_gfsk = 1;
500 state.rf_mod = 2;
501 printf ("Setting symbol rate to 9600 / second\n");
502 printf ("Enabling only GFSK modulation optimizations.\n");
503 printf ("Decoding only ProVoice frames.\n");
504 }
505 else if (optarg[0] == '1')
506 {
507 opts.frame_dstar = 0;
508 opts.frame_x2tdma = 0;
509 opts.frame_p25p1 = 1;
510 opts.frame_nxdn48 = 0;
511 opts.frame_nxdn96 = 0;
512 opts.frame_dmr = 0;
513 opts.frame_provoice = 0;
514 printf ("Decoding only P25 Phase 1 frames.\n");
515 }
516 else if (optarg[0] == 'i')
517 {
518 opts.frame_dstar = 0;
519 opts.frame_x2tdma = 0;
520 opts.frame_p25p1 = 0;
521 opts.frame_nxdn48 = 1;
522 opts.frame_nxdn96 = 0;
523 opts.frame_dmr = 0;
524 opts.frame_provoice = 0;
525 state.samplesPerSymbol = 20;
526 state.symbolCenter = 10;
527 opts.mod_c4fm = 0;
528 opts.mod_qpsk = 0;
529 opts.mod_gfsk = 1;
530 state.rf_mod = 2;
531 printf ("Setting symbol rate to 2400 / second\n");
532 printf ("Enabling only GFSK modulation optimizations.\n");
533 printf ("Decoding only NXDN 4800 baud frames.\n");
534 }
535 else if (optarg[0] == 'n')
536 {
537 opts.frame_dstar = 0;
538 opts.frame_x2tdma = 0;
539 opts.frame_p25p1 = 0;
540 opts.frame_nxdn48 = 0;
541 opts.frame_nxdn96 = 1;
542 opts.frame_dmr = 0;
543 opts.frame_provoice = 0;
544 opts.mod_c4fm = 0;
545 opts.mod_qpsk = 0;
546 opts.mod_gfsk = 1;
547 state.rf_mod = 2;
548 printf ("Enabling only GFSK modulation optimizations.\n");
549 printf ("Decoding only NXDN 9600 baud frames.\n");
550 }
551 else if (optarg[0] == 'r')
552 {
553 opts.frame_dstar = 0;
554 opts.frame_x2tdma = 0;
555 opts.frame_p25p1 = 0;
556 opts.frame_nxdn48 = 0;
557 opts.frame_nxdn96 = 0;
558 opts.frame_dmr = 1;
559 opts.frame_provoice = 0;
560 printf ("Decoding only DMR/MOTOTRBO frames.\n");
561 }
562 break;
563 case 'm':
564 if (optarg[0] == 'a')
565 {
566 opts.mod_c4fm = 1;
567 opts.mod_qpsk = 1;
568 opts.mod_gfsk = 1;
569 state.rf_mod = 0;
570 }
571 else if (optarg[0] == 'c')
572 {
573 opts.mod_c4fm = 1;
574 opts.mod_qpsk = 0;
575 opts.mod_gfsk = 0;
576 state.rf_mod = 0;
577 printf ("Enabling only C4FM modulation optimizations.\n");
578 }
579 else if (optarg[0] == 'g')
580 {
581 opts.mod_c4fm = 0;
582 opts.mod_qpsk = 0;
583 opts.mod_gfsk = 1;
584 state.rf_mod = 2;
585 printf ("Enabling only GFSK modulation optimizations.\n");
586 }
587 else if (optarg[0] == 'q')
588 {
589 opts.mod_c4fm = 0;
590 opts.mod_qpsk = 1;
591 opts.mod_gfsk = 0;
592 state.rf_mod = 1;
593 printf ("Enabling only QPSK modulation optimizations.\n");
594 }
595 break;
596 case 'u':
597 sscanf (optarg, "%i", &opts.uvquality);
598 if (opts.uvquality < 1)
599 {
600 opts.uvquality = 1;
601 }
602 else if (opts.uvquality > 64)
603 {
604 opts.uvquality = 64;
605 }
606 printf ("Setting unvoice speech quality to %i waves per band.\n", opts.uvquality);
607 break;
608 case 'x':
609 if (optarg[0] == 'x')
610 {
611 opts.inverted_x2tdma = 0;
612 printf ("Expecting non-inverted X2-TDMA signals.\n");
613 }
614 else if (optarg[0] == 'r')
615 {
616 opts.inverted_dmr = 1;
617 printf ("Expecting inverted DMR/MOTOTRBO signals.\n");
618 }
619 break;
620 case 'A':
621 sscanf (optarg, "%i", &opts.mod_threshold);
622 printf ("Setting C4FM/QPSK auto detection threshold to %i\n", opts.mod_threshold);
623 break;
624 case 'S':
625 sscanf (optarg, "%i", &opts.ssize);
626 if (opts.ssize > 128)
627 {
628 opts.ssize = 128;
629 }
630 else if (opts.ssize < 1)
631 {
632 opts.ssize = 1;
633 }
634 printf ("Setting QPSK symbol buffer to %i\n", opts.ssize);
635 break;
636 case 'M':
637 sscanf (optarg, "%i", &opts.msize);
638 if (opts.msize > 1024)
639 {
640 opts.msize = 1024;
641 }
642 else if (opts.msize < 1)
643 {
644 opts.msize = 1;
645 }
646 printf ("Setting QPSK Min/Max buffer to %i\n", opts.msize);
647 break;
648 case 'r':
649 opts.playfiles = 1;
650 opts.errorbars = 0;
651 opts.datascope = 0;
652 state.optind = optind;
653 break;
654 default:
655 usage ();
656 exit (0);
657 }
658 }
659
660
661 if (opts.resume > 0)
662 {
663 openSerial (&opts, &state);
664 }
665
666 if (opts.playfiles == 1)
667 {
668 opts.split = 1;
669 opts.playoffset = 0;
670 opts.delay = 0;
671 openAudioOutDevice (&opts, 8000);
672 }
673 else if (strcmp (opts.audio_in_dev, opts.audio_out_dev) != 0)
674 {
675 opts.split = 1;
676 opts.playoffset = 0;
677 opts.delay = 0;
678 openAudioOutDevice (&opts, 8000);
679 openAudioInDevice (&opts);
680 }
681 else
682 {
683 opts.split = 0;
684 opts.playoffset = 25; // 38
685 opts.delay = 0;
686 openAudioInDevice (&opts);
687 opts.audio_out_fd = opts.audio_in_fd;
688 }
689
690 if (opts.playfiles == 1)
691 {
692 playMbeFiles (&opts, &state, argc, argv);
693 }
694 else
695 {
696 liveScanner (&opts, &state);
697 }
698 cleanupAndExit (&opts, &state);
699 return (0);
700 }
701