sampleio.c 2.85 KB
#include <audio.h>
#include "playraw.h"

#define MAXSIZE 2048

static ALport port;

int
initaudio(int nchannels, int fs)

{
  ALconfig config;
  long pvbuffer[2];

  if (!(config = ALnewconfig ()))
  {
    fprintf(stderr,"Audio config failed\n");
    exit (1);
  }
  ALsetwidth(config, AL_SAMPLE_16);
  if (nchannels == 1)
    ALsetchannels(config, AL_MONO);
  else
    ALsetchannels(config, AL_STEREO);
  if (!(port = ALopenport("MPEG audio", "w", config)))
  {
    fprintf(stderr,"Can't allocate an audio port\n");
    exit (1);
  }

  /* set sample rate */

  pvbuffer[0] = AL_OUTPUT_RATE; pvbuffer[1] = fs;
  ALsetparams(AL_DEFAULT_DEVICE, pvbuffer, 2);
  ALfreeconfig(config);
  return(0);
}

void
clearaudio()
{
  while(ALgetfilled(port) > 0)
    sleep(1);
  ALcloseport(port);
}

static void 
writeaudio(void *buffer, int nsam)
{
  ALwritesamps(port, buffer, (long) nsam);
}

static void
fmtchan(int size, char *p, int *data, int stride)
{
	int i, c;

	for(i=0; i<size; i++) {
		c = *data++;
		if(c < -0x7fff)
		  c = -0x7fff;
		if(c > 0x7fff)
		  c = 0x7fff;
		p[0] = c>>8;
		p[1] = c;

		p += stride;
	}
}

void 
writeout(FILE *outfd, int size, int *l_out, int *r_out, int chans)
{
  static char obuf[MAXSIZE<<1];
  int i;

  switch (chans){
  case 2:
    fmtchan(size, obuf, l_out, 2*chans);
    fmtchan(size, obuf+2, r_out, 2*chans);
    if (outfd!=NULL){
      if ((i=fwrite(obuf, 1, 4*size, outfd)) != 4*size) {
	fprintf(stderr, "write error %d\n",i);
	exit(1); 
      } 
    }
    else
      writeaudio(obuf, 2*size);
    break;
  case 1: /* For mono only use the left channel buffer */
    fmtchan(size, obuf, l_out, 2);
    if (outfd!=NULL){
      if ((i=fwrite(obuf, 1, 2*size, outfd)) != 2*size) {
	fprintf(stderr, "write error %d\n",i);
	exit(1); 
      } 
    }
    else
      writeaudio(obuf, size);
    break;
  default:
    fprintf(stderr,"Error in number of channels\n");
    exit(1);
  }
}

static void 
intset(int *lp, int x, long size)
{
for (; size>0; size--)
  *lp++ = x;
}

static long 
getsample(FILE *bin, int *p)
{
  long c1, c2;
  
  c1 = fgetc(bin);	/* msb */
  c2 = fgetc(bin);	/* lsb */
  if(c2 < 0)
    return 1;
  c2 |= c1<<8;
  if(c2 & (1<<15))
    c2 |= ~((1<<15) - 1);
  *p = (int) c2;
  return 0;
}

int 
getstereodata(FILE *bin, int eof, int size, int *lp, int *rp)
{
  long i;
  
  i = 0;
  if (eof) goto clr;
  
  for(; i<size; i++) {
    if(getsample(bin, lp))
      break;
    if(getsample(bin, rp))
      break;
    lp++;
    rp++;
  }
  if(i == size)
    return 0; 
  
  if(i == 0)
    eof = 1;
 clr:
  intset(lp, 0, size-i);
  intset(rp, 0, size-i);
  return eof;
}

int 
getmonodata(FILE *bin, int eof, int size, int *mp)
{
  long i;
  
  i = 0;
  if (eof) goto clr;
  
  for(; i<size; i++) {
    if(getsample(bin, mp))
      break;
    mp++;
  }
  if(i == size)
    return 0; 
  
  if(i == 0)
    eof = 1;
 clr:
  intset(mp, 0, size-i);
  return eof;
}