/* Copyright (c) 1991-2002 Doshita Lab. Speech Group, Kyoto University */
/* Copyright (c) 2000-2002 Speech and Acoustics Processing Lab., NAIST */
/*   All rights reserved   */

/* adin_mic_o2.c --- adin microphone library for IRIX6.x */

/* $Id: adin_mic_o2.c,v 1.2 2002/09/11 22:01:50 ri Exp $ */

/* test on IRIX6.4 (SGI O2 workstation) */

/*
 * Other mixer program is needed to setup mic device
 * (mute/unmute, volume control, etc.)
 */

#include <sent/stddefs.h>
#include <sent/adin.h>

/* sound header */
#include <audio.h>
static ALconfig ac;		/* local port settings */
static ALport aport;		/* audio port */

/* sub function: initialize global audio interface */
static boolean
adin_o2_setup_global(double rate)
{
  int device;
  ALpv setPVbuf[4];

  setPVbuf[0].param   = AL_INTERFACE;
  setPVbuf[0].value.i = alGetResourceByName(AL_SYSTEM, "Microphone", AL_INTERFACE_TYPE);
  setPVbuf[1].param   = AL_MASTER_CLOCK;
  setPVbuf[1].value.i = AL_CRYSTAL_MCLK_TYPE;
  setPVbuf[2].param   = AL_RATE;
  setPVbuf[2].value.ll= alDoubleToFixed(rate);
  device = alGetResourceByName(AL_SYSTEM, "Microphone", AL_DEVICE_TYPE);
  if (alSetParams(device, setPVbuf, 3) < 0) {
    return FALSE;
  } else {
    return TRUE;
  }
}

/* check audio port resource and initialize */
/* will be called once at startup time */
boolean
adin_mic_standby(int sfreq, void *dummy)
{
  long rate;
  long prec = AL_SAMPLE_16;
  long encd = AL_SAMPFMT_TWOSCOMP;
  long chan = AL_MONO;

  /* global setup */
  rate = sfreq;
  if (adin_o2_setup_global((double)rate) == FALSE) { /* failed */
    j_printerr("cannot setup microphone device (global)\n");
    return(FALSE);
  }

  /* local parameter setup */
  if ((ac = ALnewconfig()) == 0) {
    j_printerr("cannot config microphone device (local)\n");
    return(FALSE);
  }
  ALsetqueuesize(ac, rate * 2 * 1); /* 2 sec. of mono. */
  ALsetwidth(ac, prec);
  ALsetchannels(ac, chan);
  ALsetsampfmt(ac, encd);

  j_printf("local microphone port successfully initialized\n");
  return(TRUE);
}
  

/* start recording */
boolean
adin_mic_start()
{
  /* open audio port */
  aport = ALopenport("mic","r",ac);
  if (aport == (ALport)(0)) {
    j_printerr("cannot open microphone audio port for reading\n");
    return(FALSE);
  }

  return(TRUE);
}

/* stop recording */
boolean
adin_mic_stop()
{
  /* close audio port */
  ALcloseport(aport);
  return(TRUE);
}

/* read samples from audio device */
/* try to read `sampnum' samples and returns actual sample num recorded */
int
adin_mic_read(SP16 *buf, int sampnum)
{
  long cnt;

  cnt = ALgetfilled(aport);	/* get samples currently stored in queue */
  if (cnt > sampnum) cnt = sampnum;
  if (ALreadsamps(aport, buf, cnt) < 0) { /* get them */
    j_printerr("Error: failed to read sample\n");
    return(-2);			/* return negative on error */
  }
  return cnt;
}
