home *** CD-ROM | disk | FTP | other *** search
- /* Copyright (C) 1993 Peter Edward Cann */
-
- #include<stdio.h>
- #include<fcntl.h>
- #include<sys\types.h>
- #include<sys\stat.h>
- #include<time.h>
- #include<signal.h>
- #include<bios.h>
- #include"port.h"
-
-
- sendchar(c)
- unsigned char c;
- {
- while(!((inp(basereg+STATREG)&TXMTMASK)&&(inp(basereg+MSTATREG)&CTSMASK)));
- outp(basereg, c);
- }
-
- #define VBUFSIZ 1024
-
- unsigned char vbuf[VBUFSIZ];
- int fd, vbufi;
-
- putbyte(c)
- unsigned char c;
- {
- if(vbufi>=VBUFSIZ)
- if(write(fd, vbuf, vbufi)!=vbufi)
- {
- printf("Write error; out of disk?\n");
- sendchar('X'&31);
- while(!(inp(basereg+STATREG)&TXSHMTMASK));
- cleanup(0);
- exit(138);
- }
- else
- vbufi=0;
- vbuf[vbufi++]=c;
- }
-
- int follow;
-
- quit()
- {
- sendchar('X'&31);
- while(!(inp(basereg+STATREG)&TXSHMTMASK));
- cleanup(0);
- exit(129);
- }
-
- sendstr(str)
- char *str;
- {
- int i;
- for(i=0;str[i]!='\0';++i)
- sendchar(str[i]);
- }
-
- int follow;
-
- #define NSCANS 3
- unsigned char scans[NSCANS][16]={"CONNECT\r\n", "ERROR\r\n", "VCON\r\n"};
- #define SCANTIMEOUT 16
-
- int scan()
- {
- time_t timestamp;
- int i, j, scani[NSCANS];
- timestamp=time(NULL);
- for(i=0;i<NSCANS;++i)
- scani[i]=0;
- while(1)
- {
- while(follow==index)
- {
- if(kbhit())
- getch();
- if((time(NULL)-timestamp)>SCANTIMEOUT)
- {
- for(j=0;j<NSCANS;j++)
- scani[j]=0;
- return(-1);
- }
- }
- putch(buf[follow]);
- for(i=0;i<NSCANS;i++)
- if(scans[i][scani[i]]==buf[follow])
- {
- scani[i]++;
- if(scans[i][scani[i]]=='\0')
- {
- for(j=0;j<NSCANS;j++)
- scani[j]=0;
- follow++;
- follow%=TBUFSIZ;
- return(i);
- }
- }
- else
- scani[i]=0;
- follow++;
- follow%=TBUFSIZ;
- }
- }
-
- #define MAXCHECKS 64
- unsigned char checks[MAXCHECKS];
- int nchecks;
-
- #define XVINIT 255
-
- main(argc, argv)
- int argc;
- char **argv;
- {
- int dleflag, timecnt, maxsecs, i, xval, tmpi;
- unsigned kc;
- unsigned char c, fname[128];
- time_t ts;
- xval=XVINIT;
- if(argc<5)
- {
- printf("USAGE: voicerx <comnum> <speed> <file> <max secs> [endcode] ...\n");
- printf("Endcodes are shielded codes, reported as exit codes starting with 0 (first).\n");
- printf("Real live errors are >128, which is play completed.\n");
- printf("Multi-char args are assumed hex.\n");
- exit(140);
- }
- if(!argv[3][0])
- {
- printf("File argument is null.\n");
- exit(151);
- }
- if(argv[3][strlen(argv[3])-1]=='\\')
- sprintf(fname, "%s%08lx.vce", argv[3], time(NULL));
- else
- strcpy(fname, argv[3]);
- if((fd=open(fname, O_WRONLY|O_BINARY|O_CREAT|O_TRUNC, S_IWRITE))==-1)
- {
- printf("Unable to open voice file %s for write.\n", fname);
- exit(150);
- }
- maxsecs=atoi(argv[4]);
- nchecks=0;
- while(1)
- {
- if(nchecks>=MAXCHECKS)
- {
- printf("Too many endcodes for this compile.\n");
- exit(145);
- }
- if(nchecks>=(argc-5)) /* Waste a few usec; who cares? */
- break;
- if(!argv[nchecks+5][0])
- {
- printf("Endcode %d null; exiting.\n", nchecks);
- exit(141);
- }
- if(!argv[nchecks+5][1])
- checks[nchecks]=argv[nchecks+5][0];
- else
- if(sscanf(argv[nchecks+5], "%x", &tmpi)!=1)
- {
- printf("Bad scan endcode %d; exiting.\n", nchecks);
- exit(142);
- }
- else
- checks[nchecks]=tmpi;
- nchecks++;
- }
- vbufi=0;
- comnum=atoi(argv[1])-1;
- speed=atoi(argv[2]);
- databits='8';
- parity='n';
- stopbits='1';
- setport();
- readset();
- follow=index=0;
- timecnt=0;
- printf("Recording voice. Control-D to end; Control-C to nuke.\n");
- setup();
- signal(SIGINT, quit);
- ts=time(NULL);
- sendstr("AT#VRX\r");
- switch(scan())
- {
- case -1:
- cleanup(0);
- printf("Timeout waiting for CONNECT.\n");
- exit(130);
- break;
- case 0:
- break;
- case 1:
- cleanup(0);
- printf("Modem rejected play command.\n");
- exit(131);
- break;
- default:
- cleanup(0);
- printf("Strange scan() return.\n");
- exit(132);
- break;
- }
- dleflag=0;
- while(1)
- {
- while(follow==index)
- if(_bios_keybrd(_KEYBRD_READY))
- {
- kc=_bios_keybrd(_KEYBRD_READ);
- if((kc&0xff)==('C'&31))
- {
- sendchar('\r'); /* Try anyway */
- quit();
- }
- else if((kc&0xff)==('D'&31))
- {
- putch('^');
- putch('D');
- sendchar('\r');
- xval=254;
- }
- }
- if(timecnt++>=1024)
- {
- timecnt=0;
- if(_bios_keybrd(_KEYBRD_READY))
- {
- kc=_bios_keybrd(_KEYBRD_READ);
- if((kc&0xff)==('C'&31))
- quit();
- else if((kc&0xff)==('D'&31))
- {
- sendchar('\r');
- xval=254;
- }
- }
- if((time(NULL)-ts)>maxsecs)
- {
- sendchar('\r');
- xval=128;
- }
- }
- c=buf[follow++];
- if(follow>=TBUFSIZ)
- follow=0;
- if(c==0x10)
- {
- if(dleflag)
- {
- putbyte(0x10);
- putbyte(0x10);
- dleflag=0;
- }
- else
- dleflag=1;
- }
- else if(!dleflag)
- putbyte(c);
- else if(c==0x03)
- {
- putbyte(0x10);
- putbyte(0x03);
- if(write(fd, vbuf, vbufi)!=vbufi)
- {
- printf("Disk buffer flush error.\n");
- exit(160);
- }
- scan(); /* Wait for VCON or whatever */
- cleanup(0);
- exit(xval);
- }
- else if(xval==XVINIT)
- {
- putch(c);
- dleflag=0;
- for(i=0;i<nchecks;i++)
- if(c==checks[i])
- {
- sendchar('X'&31);
- xval=i;
- }
- }
- else
- dleflag=0;
- }
- printf("Programming error; fell through endless while loop!\n");
- cleanup(0);
- exit(250);
- }