/* audecho.c
   L. Stewart October 13, 1982  9:15 PM
   L. Stewart November 30, 1982  10:20 AM, removed net stuff
   L. Stewart March 11, 1983  9:12 AM, new slave stuff
 */

#include "Lark.h"
#include "Env.h"
#include "Queue.h"
#include "LarkSlave.h"
#include "LarkNet.h"
#include "Pup.h"

extern InitOS();
extern Block();
extern SSEnable();
extern wf();
extern InitQueue();
extern GetFixed();
extern InitNContext();
extern Enqueue();
extern CallContext();
extern GetChar();
extern InitAnalog();
extern SetInGain();
extern SetOutGain();
extern StartSlave();

char *obuf1, *obuf2, *obuf3, *inbuf1, *inbuf2;
int *outgain, *bufptr;
int *ingain1, *ingain2, *silval1, *silval2;
int igint, ogint, tgint;

int audioMode, first;

/* booleans */
int ledb, arb, hsrb, fbb, ohb, reb, stb, xrow, xcol, encb;

/* user interface data, see CharIO.c */
extern int mlerr[3];

/* process machinery */
extern struct Queue ctxQ;

StateProc()
  {
  for (;;) {
    Block();
    CheckAS();
    };
  };

AudioProc()
  {
  for (;;) {
    Block();
    if (audioMode) TryEcho();
    };
  };

ControlProc()
  {
  int result;
  result = SSEnable(mlerr);
  if (result) wf(" ##\r");
  for (;;) {
    wf("% ");
    MainCmd();
    };
  };

main()
  {
  int space, ctx;
  InitOS();
  wf("\rAudio test, ? for help.\r");
  Restart();
  InitQueue(&ctxQ);
  space = GetFixed(600);
  ctx = InitNContext("AudioProc", space, 600, &AudioProc);
  Enqueue(&ctxQ, ctx);
  space = GetFixed(600);
  ctx = InitNContext("ControlProc", space, 600, &ControlProc);
  Enqueue(&ctxQ, ctx);
  space = GetFixed(600);
  ctx = InitNContext("StateProc", space, 600, &StateProc);
  Enqueue(&ctxQ, ctx);
  InitPupLevel1(&ctxQ, 10, defaultPupDataBytes);
  ELoad();
  for (;;) {
    CheckWDT();
    CtxListStart();
    CallContext(ctxQ.head);
    CtxListEnd();
    };
  };

MainCmd()
  {
  switch (GetChar()) {
    case '?': { MainHelp(); break; };
    case 'a': { AudioCmd(); break; };
    case 'b': { PrintBP(); break; };
    case 'E': { ElecPhone(); break; };
    case 'f': { SetTS(); break; };
    case 'g': { GainCmd(); break; };
    case 'm': { NewAudio(); break; };
    case 'p': { PrintAS(); break; };
    case 'r': { Restart(); break; };
    case 's': { PSV(); break; };
    case 't': { ToggleCmd(); break; };
    case 'x': { XbarOn(); break; };
    case 'y': { XbarOff(); break; };
    case 'z': { XbarReset(); break; };
    default: wf("\r unknown command\r");
    };
  };

AudioCmd()
  {
  char c;
  wf("a ");
  c = GetChar();
  switch (c) {
    case '1': case '2': case '3': case 'A':
    case '4': case '5': case '6': case 'B':
    case '7': case '8': case '9': case 'C':
    case '0': case '*': case '#': case 'D': {
      LocPlayDTMF(c, 10000, 0, false, 3);
      break;
      };
    case 'p': { CallNum(); break; };
    case 'd': { PlayTone(350, 440, 100, 0, 100, false, tgint); break; };
    case 'e': { TogEcho(); break; };
    case 'r': { PlayTone(440, 480, 2000, 4000, 3, false, tgint); break; };
    case 'b': { PlayTone(480, 620, 500, 500, 10, false, tgint); break; };
    case 'z': { SetB(1, obuf1); break; };
    case 'x': { SetB(2, obuf2); break; };
    case 'c': { SetB(3, obuf3); break; };
    case 'm': { SPMode(); break; };
    case '?': { AudioHelp(); break; };
    default: AudioIdle();
    };
  };

GainCmd()
  {
  wf("gain ");
  switch (GetChar()) {
    case 'I': { SetIG(); break; };
    case 'O': { SetOG(); break; };
    case 'i': { CycleIG(); break; };
    case 'o': { CycleOG(); break; };
    case 't': { CycleTG(); break; };
    default: GainHelp();
    };
  };

ToggleCmd()
  {
  wf("toggle ");
  switch (GetChar()) {
    case 'a': { TogARelay(); break; };
    case 'e': { TogEncrypt(); break; };
    case 'f': { TogFallback(); break; };
    case 'h': { TogHSRelay(); break; };
    case 'l': { TogLed(); break; };
    case 'o': { TogOnHook(); break; };
    case 'r': { TogRingEnable(); break; };
    case 's': { TogSidetone(); break; };
    default: ToggleHelp();
    };
  };

static Restart()
  {
  igint = ogint = 0;
  tgint = 3;
  audioMode = AMOff;
  first = false;
  ledb = ohb = fbb = reb = stb = encb = false;
  InitAnalog();
  inbuf1 = InBuf1;
  obuf1 = OutBuf1;
  obuf2 = OutBuf2;
  obuf3 = OutBuf3;
  inbuf2 = InBuf2;
  ingain1 = In1Gain;
  ingain2 = In2Gain;
  outgain = OutGain;
  bufptr = BufPtr;
  silval1 = Sil1Val;
  silval2 = Sil2Val;
  SetInGain(3, 0)
  SetOutGain(0)
  StartSlave(0, 0);
  InitToneStuff();
  };