/* Larkaud.c
   L. Stewart   November 11, 1982  12:11 PM

   L. Stewart   November 1, 1982  9:01 AM,  other stuff
   L. Stewart, November 11, 1982  12:08 PM, CheckFromNet
   L. Stewart, December 7, 1982  1:24 PM, New relays
   L. Stewart, December 8, 1982  4:06 PM, dismiss command, LarkSlave refs
   L. Stewart, January 14, 1983  4:09 PM, Lark.mesa revisions
   L. Stewart, March 2, 1983  3:31 PM, Larkinitial connections
 */

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

/* context package */
extern Block();
extern Free();
extern int sysZone;
extern int totAv;
extern int largest;

/* Allocate package */
extern Allocate();

/* Lark stuff */
extern InitAnalog();
extern SetInGain();
extern SetOutGain();
extern StartSlave();
extern PlayTone();

/* CharIO package */
extern wf2();
extern wf4();

extern int DEBUG;
extern int wToneCB;

int first;

AudioProcess()
  {
  for (;;) {
    Block();
    TryEcho();
    Block();	/* should this be here? */
    CheckFromNet(IOut1);
    CheckFromNet(IOut2);
    CheckFromNet(IOut3);
    };
  };

AudioStuff()
  {
  first = false;
  InitAnalog();  /* redundant probably, it is in InitOS, but restarts... */
  InitNetStuff();
  InitToneStuff();
  SetInGain(0, 0)
  SetInGain(1, 0)
  SetOutGain(0)
  StartSlave(1, 0);
  Revert(false);
  RevertHS(false);
  SetXbar(1, 4);
  SetXbar(0, 3);
  SetXbar(3, 0);
  };

AudCmd(p)
  struct EvSeq *p;
  {
  int i, on;
  char d, e;
  if (p->length > 20) return;
  for (i = 0; i < p->length; i += 1) {
    Block();
    d = p->evs[i].device;
    e = p->evs[i].event;
    if (e == 144) on = true;
    else on = false;
    switch (p->evs[i].device) {
      case 4: PutC(0, e); break;
      case 5: PutC(1, e); break;
      case 8: Revert(on); break;
      case 9: GoOffHook(on); break;
      case 10: SideTone(on); break;
      case 11: RingEnable(on); break;
      case 12: Led(on); break;
      case 13: XbarClear(); break;
      case 14: SetTS(e); break;
      case 15: SetVoice(e); break;
      case 16: case 17:
      case 18: case 19:
        SetTable(d, e); break;
      case 22: YXBar(e); break;
      case 23: XXBar(e); break;
      case 24: RevertHS(on); break;
      case 25: ARelay(on); break;
      case 27: { on = e; Dismiss(on * 10); break; };
      default: break;
      };
    };
  };

static SetTS(c)
  char c;
  {
  if (c == 147) SetCodec(0);
  if (c == 148) SetCodec(0x0c);
  };

static YXBar(c)
  char c;
  {
  ClearXbar(((c >> 4) & 0x0f), (c & 0x0f));
  };

static XXBar(c)
  char c;
  {
  SetXbar(((c >> 4) & 0x0f), (c & 0x0f));
  };

static SetVoice(c)
  char c;
  {
  switch (c) {
    case 159: StartSlave(1, 0); break;
    case 160: StartSlave(2, 0); break;
    default: StartSlave(1, 0); break;
    };
  };

static SetTable(d, e)
  char d, e;
  {
  int table;
  table = e - 149;
  switch (d) {
    case 16: SetInGain(0, table); break;
    case 17: SetInGain(1, table); break;
    case 18: SetOutGain(table); break;
    case 19: SetOutGain(table); break;
    default: break;
    };
  };

/* Actual calls via RPC */

Reset(rName)
  struct ShortSTRING *rName;
  {
  if (DEBUG) wf1("Reset[%r]\r", rName);
  AudioStuff(); /* initialize */
  /* place to hang this */
  Allocate(sysZone, 0);
  wf2("Alloc: totAv = %u, largest = %u\r", totAv, largest);
  Free(sysZone, rName);
  };

int GenerateTones(f1, f2, modulation, on, off, repetitions, waveTable, queueIt, notify)
  int f1, f2, modulation, on, off, repetitions, waveTable, queueIt, notify;
  {
  int i;
  i = PlayTone(f1, f2, on, off, repetitions, queueIt, waveTable, notify);
  return ((i) ? 1: 0);
  };

Disconnect(junk, id)
  int junk, id;
  {
  StopNet(id);
  };

PleaseRegister()
  {
  if (DEBUG) wf("PleaseRegister[]\r");
  };

int WhatIsStatus(which)
  int which;
  {
  int res;
  if (DEBUG) wf1("WhatIsStatus[which: %d] = [0, NIL]\r", which);
  /* args[2] = 0; */ /* FIR can't really handle multiple returns */
  if (which >= 3) res = 0;
  else res = which + 1;
  return (res);
  };

int WhatAreConnections(which)
  int which;
  {
  int res;
  if (DEBUG) wf1("WhatAreConnections[which: %d] = [0, NIL]\r", which);
  /* args[2] = 0; */ /* FIR can't really handle multiple returns */
  if (which >= 3) res = 0;
  else res = which + 1;
  return (res);
  };

int WhatAreTones()
  {
  if (DEBUG) wf("WhatAreTones[] = [FALSE]\r");
  return ((wToneCB) ? 1: 0);
  };