📄 netplay.c
字号:
/*---------------------------------------------------------------------------+| || Joseph T. Buck, Entropic Processing, Inc. || Modified by Alan Parker for SPS to Vax| || The 'play' program creates a temporary ILS file from a subrange of an SDS || file, and sends it to epicen to be played on the DSC. || || Syntax: play [options] file || Options: || -g gain || gain is a floating value. The file is multiplied by this || value to form the temporary file || -p range || range is a range of points. Only those points are played || the first point is 1 || -f range || range is a range of frames (default frame size = 100) || the first frame is 1 || -w width || changes the frame size || -s range || range is a range of seconds. For LISTEN compatibility, the || first second is zero || -r repeats || number of repetitions || -c chan || channel number || -n nfilt || filter number || -x debug_level || |+---------------------------------------------------------------------------*/#ifndef lint static char *sccs_id = "@(#)netplay.c 1.1 5/22/86";#endif#define MAX_SHORT 32767#define MIN_SHORT -32768#define SIZ 1024#include <stdio.h>#include <sps/sps.h>#include <sds/ftypes.h>#define VMAX 1.0e6#define BYTE_REV /* On for 68k, off for Vax */#define SYNTAX USAGE \("play [-[spf] range] [-w fsiz] [-c chan] [-n nfil] [-r nrpt] [-g gain] file");#include "config.h"#define Fprintf (void)fprintfstatic long ihead[64] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};#ifdef USGint sprintf();void exit(), perror(), rewind();#elsechar *sprintf();#endiflong long_reverse ();int debug_level = 0;union s_union { short sval; char scval[sizeof (short)];};union l_union { long lval; char lcval[sizeof (long)];};main (argc, argv)int argc;char **argv;{ int c, i, ipwr, xisf; extern optind; extern char *optarg, *mktemp (); int nrep = 1, nfilt = 0, channel = 0; char *p_switch = NULL, *s_switch = NULL, *f_switch = NULL, buf[200]; FILE * istrm, *tstrm, *pipe, *popen(); char *template = "/usr/tmp/plyXXXXXX"; struct header *ih; int start_p, end_p, start_s, end_s, start_f, end_f; int isf, nsec, rem, np, fwidth = 100, gflag = 0; int first = 1, first_sf, nptot = 0; double gain, atof (); while ((c = getopt (argc, argv, "p:s:r:n:c:w:f:g:x:")) != EOF) { switch (c) { case 'x': debug_level = atoi (optarg); break; case 'g': gflag++; gain = atof (optarg); break; case 'c': channel = atoi (optarg); break; case 'r': nrep = atoi (optarg); break; case 'n': nfilt = atoi (optarg); break; case 'p': p_switch = optarg; break; case 'f': f_switch = optarg; break; case 'w': fwidth = atoi (optarg); break; case 's': s_switch = optarg; break; default: SYNTAX; } } if (optind >= argc) SYNTAX; while (optind < argc) { TRYOPEN ("play", argv[optind], "r", istrm); ih = read_header (istrm); if (ih -> common.type != FT_SD) { Fprintf (stderr, "play: %s is not speech data\n", argv[optind]); exit (1); } start_p = 1; end_p = ih -> common.ndrec + start_p - 1; isf = ih -> hd.sd->sf; start_s = (start_p - 1) / isf; end_s = (end_p + isf - 1) / isf; start_f = (start_p - 1) / fwidth + 1; end_f = (end_p + fwidth - 1) / fwidth; if (p_switch) range_switch (p_switch, &start_p, &end_p, 1); else if (s_switch) { range_switch (s_switch, &start_s, &end_s, 1); start_p = start_s * isf + 1; end_p = end_s * isf; if (end_p <= start_p) end_p += isf; } else if (f_switch) { range_switch (f_switch, &start_f, &end_f, 1); start_p = (start_f - 1) * fwidth + 1; end_p = end_f * fwidth; } if (start_p > end_p) { Fprintf (stderr, "play: start > end\n"); exit (1); } else if (end_p > ih -> common.ndrec) { Fprintf (stderr, "play: %s is not long enough\n", argv[optind]); Fprintf (stderr, "end_p = %d, last point = %d\n", end_p, ih -> common.ndrec); exit (1); } skiprec (istrm, start_p - 1, size_rec (ih)); if (first) { /* Create temporary file */ if ((tstrm = fopen (mktemp (template), "w+")) == NULL) CANTOPEN ("play", template); (void) unlink (template); /* Write ILS header - only care about sf, check values */ first_sf = isf; if (isf < 100.0 || isf > VMAX) { ipwr = log10(isf) - 4; xisf = isf / pow(10.0,(double)ipwr); } else { xisf = isf + 0.5; ipwr = 0; } if (debug_level) Fprintf(stderr, "play: xisf %d, ipwr %d\n",xisf,ipwr);#ifdef BYTE_REV ihead[61] = long_reverse ((long) xisf); ihead[60] = long_reverse ((long) ipwr); ihead[62] = long_reverse ((long) FT_SAMPLED_DATA);#else ihead[61] = xisf; ihead[60] = ipwr; ihead[62] = FT_SAMPLED_DATA;#endif if (!fwrite ((char *) ihead, sizeof ihead, 1, tstrm)) write_error (tstrm, template); } else if (isf != first_sf) { Fprintf (stderr, "play: all files must have same sample freq\n"); exit (1); } /* copy data from input to output. For 'w' file, simpler copy */ np = end_p - start_p + 1; if (debug_level) Fprintf (stderr, "%s Copying %d samples\n", argv[optind], np); if (ih -> common.nfloat == 1) { float data[SIZ]; int n = SIZ, npleft = np; while (npleft > 0) { if (npleft < n) n = npleft; get_fdata (istrm, 'f', data, n); if (gflag) for (i=0; i<n; i++) data[i] *= gain; for (i = 0; i < n; i++) { union s_union tmp; if (data[i] < MIN_SHORT) tmp.sval = MIN_SHORT; else if (data[i] > MAX_SHORT) tmp.sval = MAX_SHORT; else tmp.sval = data[i];#ifdef BYTE_REV putc (tmp.scval[1], tstrm); putc (tmp.scval[0], tstrm);#else putc (tmp.scval[0], tstrm); putc (tmp.scval[1], tstrm);#endif } npleft -= n; } } else { short data[SIZ]; int n = SIZ, npleft = np; while (npleft > 0) { if (npleft < n) n = npleft; if ((n = fread ((char *)data, n, sizeof *data, istrm)) == 0) break;#ifdef BYTE_REV for (i = 0; i < n; i++) { union s_union tmp; tmp.sval = data[i]; putc (tmp.scval[1], tstrm); putc (tmp.scval[0], tstrm); }#else if (fwrite ((char *)data, sizeof *data, n, tstrm) != n) write_error(tstrm, template);#endif npleft -= n; } } nptot += np; first = 0; optind++; }/* Round up to an integral number of seconds, if needed */ nsec = nptot / isf; rem = nptot % isf; if (rem != 0) { int npad = (isf - rem) * sizeof (short); if (debug_level) Fprintf (stderr, "Adding %d zero samples\n", isf - rem); nsec++; while (npad--) putc (0, tstrm); }/* Temporary file is complete. Close files. */ (void) fclose (istrm); rewind (tstrm); if (debug_level) Fprintf (stderr, "Starting %s's play demon\n", HOST);/* Invoke the DSC listen routine on HOST. Clear debug bit 1 */ (void) sprintf (buf, "rsh %s %s %d %d %d %d %d %d %d", HOST, DEMON, nsec, nrep, isf, ipwr, channel, nfilt, debug_level & ~1); if ((pipe = popen (buf, "w")) == NULL) { perror ("play: can't start play demon on remote host"); exit (2); } if (debug_level) Fprintf (stderr, "Transmitting speech to %s\n", HOST); while ((c = getc (tstrm)) != EOF) putc (c, pipe); (void) fclose (tstrm); (void) pclose (pipe); if (debug_level) Fprintf (stderr, "Speech transfer complete\n"); exit (0); /* NOTREACHED */}write_error (strm, name)FILE *strm;char *name;{ char buf[80]; (void) sprintf (buf, "play: error writing to temp file %s", name); perror (buf); (void) fclose (strm); (void) unlink (name); exit (2);}#ifdef BYTE_REVlonglong_reverse (in)long in;{ union l_union tmp1, tmp2; register int i; tmp1.lval = in; for (i = 0; i < sizeof in; i++) tmp2.lcval[i] = tmp1.lcval[sizeof in - i - 1]; return tmp2.lval;}#endif
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -