Sample voice functions for Rockwell modems


4/16/97

I wrote some 'C' functions to make it easier to write voice mail applications using the Rockwell chipset. I tried using the VAPI library from Rockwell, but it was way too complicated, this is really simple. You're free to do whatever you want with them, have fun!

To dowload the whole project (with voice samples and everything) click here.

// This is a very simple (and useless) answering machine program designed
// for modems using the 14.4 or 28.8 versions of the Rockwell Voice Modem
// chipset.  This program is useless because it is written as a simple
// example, but about ten minutes worth of programming could turn this into
// a real answering machine, and a little more could make it a REALLY COOL
// voice mail system.

// For the sake of clarity I wrote this as a 16 bit Windows "EasyWin" program.
// I compiled it on the Borland C++ 4.5 compiler.


/* Example written by Charlie Payne */


/* Uncomment only one of the following */
#define USER_LOCAL      /* Record and play through modem speaker/mic. */
// #define USER_REMOTE     /* Record and play through phone line */
// #define USER_MONITOR    /* Record through phone line, but play through line and speaker */

#define COM_NUMBER   3
#define QUEUE_SIZE   1024
#define MODEM_EOT    "\016\003"

#include <windows.h>
#include <iostream.h>
#include <string.h>
#include <conio.h>
#include <stdio.h>
#include <stdlib.h>

int commout(int commid, char *outstring);
void ShowError(int err, char *errorstring);
void machine(int commid);
int modemresult(int commid);
void sendchar(int commid, char character);
int rcvchar(int commid, char* character);
void playmsg(int commid, char* filename);
int recordmsg(int commid, char* filename);
void initmodem(int commid);
void answerphone(int commid);
int initport(int com_number, UINT baud_rate);
void dialspeakerphone(int commid, char* phone_number);
void answerspeakerphone(int commid);


int main(void) {
   int commid;

   if ((commid=initport(COM_NUMBER, CBR_38400))==0) return 1;

   machine(commid);

   CloseComm(commid);
   return 0;
}


void machine(int commid) {
   int ring;
   char key;

   initmodem(commid);

   cout << "waiting for ring... (or press any key)\n";

   do {
      ring=modemresult(commid);

      if (kbhit()) {
         getch();
         ring=5;
         break;
      }
   } while ((ring<5) || (ring>8));

   cout << "Got ring type " << ring-5 << endl;

   answerphone(commid);

   playmsg(commid, "greet1.msg");   // "Please leave a message..."

   key=(char)recordmsg(commid, "test.msg");
   if ((key>34) && (key<58)) cout << "User pressed: " << key << endl;

   playmsg(commid, "greet2.msg");   // "Well, this is what you recorded..."
   playmsg(commid, "test.msg");

   commout(commid, "ath");    // Hang up
}


int initport(int com_number, UINT baud_rate) {
   int commid, err;
   DCB dcb;
   char temp_string[30];

   strcpy(temp_string, "COM");
   itoa(com_number, temp_string+3, 10);
   strcat(temp_string, ":24,n,8,1");

   err = BuildCommDCB(temp_string, &dcb);
   if (err < 0) {
       ShowError(err, "BuildCommDCB");
       return 0;
   }

   temp_string[4]=0;
   commid = OpenComm(temp_string, QUEUE_SIZE, QUEUE_SIZE);
   if (commid < 0) {
       ShowError(commid, "OpenComm");
       return 0;
   }

   dcb.fOutX         = FALSE;
   dcb.fInX          = FALSE;
   dcb.fOutxCtsFlow  = TRUE;
   dcb.fRtsflow      = TRUE;
   dcb.fNull         = FALSE;
   dcb.fChEvt        = FALSE;
   dcb.XonLim        = QUEUE_SIZE/2;
   dcb.XoffLim       = QUEUE_SIZE/2;
   dcb.fBinary       = TRUE;
   dcb.Id            = commid;
   dcb.BaudRate      = baud_rate;

   err = SetCommState(&dcb);
   if (err < 0) {
       ShowError(err, "SetCommState");
       return 0;
   }

   return commid;
}

void answerphone(int commid) {
   commout(commid, "AT#CLS=8");     /* Configure the modem for Voice Mode */
   commout(commid, "AT#BDR=16");    /* Set baud rate to 38400 */
   commout(commid, "ATA");          /* Answer phone */
}


void initmodem(int commid) {
   commout(commid, "AT");           /* Hey modem, are you there? */
   commout(commid, "ATV1");         /* Use english response codes */
   commout(commid, "AT-SDR=7");     /* Enable distinctive ringing detection */
   commout(commid, "AT#CLS=8");     /* Configure the modem for Voice Mode */
   commout(commid, "AT#VBS=4");     /* Set to 4-bit compression */
   commout(commid, "ATS30=60");     /* Set Disconnect Inactivity Timer to 1 minute */
   commout(commid, "AT#BDR=16");    /* Set baud rate to 38400 */
   commout(commid, "AT#VSP=20");    /* When receiving voice data, 2 seconds of silence
                                       terminates the Receive Mode. */
   commout(commid, "AT#VSD=1");     /* Enable Silence Deletion */
   commout(commid, "AT#VSS=2");     /* Set Silence Detection Tuner */
#ifdef USER_REMOTE
   commout(commid, "AT#VLS=0");     /* Normal */
#endif
#ifdef USER_MONITOR
   commout(commid, "AT#VLS=4");     /* Monitor */
#endif
// commout(commid, "AT#VLS=2");     /* Speaker only */
// commout(commid, "AT#VLS=3");     /* Mic only */
}


void playmsg(int commid, char* filename){
   FILE *in;
   char temp;

#ifdef USER_LOCAL
   commout(commid, "AT#VLS=2");  /* Speaker only */
#endif

   commout(commid, "AT#VTX");    /* Play audio stream */

   cout << "Playing file " << filename << "...\n";
   in = fopen(filename, "rb");

   while (!feof(in)) {
      fread(&temp, 1, 1, in);
      sendchar(commid, temp);
   }

   cout << "Stopped playing." << endl;
   fclose(in);

   sendchar(commid, 16);
   sendchar(commid, 3);
   cout << "got:" << modemresult(commid) << endl;
}


int recordmsg(int commid, char* filename) {
   FILE *out;
   char temp, key;

#ifdef USER_LOCAL
   commout(commid, "AT#VLS=2");  /* Speaker only */
#endif

   commout(commid, "AT#VBT=12");

   if (commout(commid, "AT#VTS=[1000,0,7]")==0) {
      while (modemresult(commid)==0) {if (kbhit()) break;}
   }

#ifdef USER_LOCAL
   commout(commid, "AT#VLS=3");  /* Mic only */
#endif

   commout(commid, "AT#VBS=4");

   cout << "Recording into file " << filename << "...  (press any key to stop)\n";

   commout(commid, "AT#VRX");

   out = fopen(filename, "wb");

   do {
      if (rcvchar(commid, &temp)!=0) {
         if (temp==16)
         {
            while (rcvchar(commid, &temp)==0) {if (kbhit()) {getch(); key=113; break;}}
            if (temp==16)
            {
               fwrite(&temp, 1, 1, out);
               fwrite(&temp, 1, 1, out);
               temp=0;
            }
            else
            {
               key=temp;
               cout << "Stopped recording because we got a: " << (int)key << endl;
               temp=16;
            }
         }
         else
            fwrite(&temp, 1, 1, out);
      }
   } while ((!kbhit()) && (temp!=16));

   fclose(out);

   commout(commid, "ATX");    /* Respond to busy cadence detection (if any) */

   return (int)key;
}


void ShowError(int err, char *errorstring) {
   cout << "Error #" << err << " in " << errorstring << endl;
}

int commout(int commid, char *outstring) {
   int i, err;

   cout << "sending: " << outstring << endl;
   for (i=0; i<strlen(outstring); i++) {
      sendchar(commid, outstring[i]);
   }
   sendchar(commid, 13);
   err=modemresult(commid);
   cout << "got:" << err << endl;

   return err;
}

void sendchar(int commid, char character) {

   COMSTAT comstat;

   do {
      GetCommError(commid, &comstat);
   } while (comstat.cbOutQue>0);

   WriteComm(commid, &character, 1);
}


int rcvchar(int commid, char* character) {
   COMSTAT comstat;

   GetCommError(commid, &comstat);
   if (comstat.cbInQue==0) return 0;

   ReadComm(commid, character, 1);
   return 1;
}


int modemresult(int commid) {
   char temp[2], tempstr[256];
   long count=0;

   temp[1]='\0';
   tempstr[0]='\0';

   while (count<100000) {

      if (rcvchar(commid, temp)==0)
         count++;
      else {
         strcat(tempstr, temp);
         count=0;
         if (strstr(tempstr, "OK")) {
            return 1;
         }
         if (strstr(tempstr, "VCON")) {
            return 2;
         }
         if (strstr(tempstr, "CONNECT")) {
            return 3;
         }
         if (strstr(tempstr, MODEM_EOT)) {
            return 4;
         }
         if (strstr(tempstr, "RING\r")) {
            return 5;
         }
         if (strstr(tempstr, "RING1")) {
            return 6;
         }
         if (strstr(tempstr, "RING2")) {
            return 7;
         }
         if (strstr(tempstr, "RING3")) {
            return 8;
         }
      }
   }
   return(0);
}


void dialspeakerphone(int commid, char* phone_number) {
   char dialstring[256];

   commout(commid, "AT#CLS=8");
   commout(commid, "AT#VRN=0");
   commout(commid, "AT#VLS=6");

   strcpy(dialstring, "ATDT");
   strcat(dialstring, phone_number);
   strcat(dialstring, "\r");
   commout(commid, dialstring);
}


void answerspeakerphone(int commid) {

   commout(commid, "AT#CLS=8");
   commout(commid, "AT#VLS=6");
   commout(commid, "ATA");
}