/*----------------------------------------------------------------------
raw.c - read and write raw audio files
by Andy Allinger, 2016-2021, released to the public domain

   Permission  to  use, copy, modify, and distribute this software and
   its documentation  for  any  purpose  and  without  fee  is  hereby
   granted,  without any conditions or restrictions.  This software is
   provided "as is" without express or implied warranty.
----------------------------------------------------------------------*/
#include <stdint.h>
#include <stdio.h>
#include <math.h>

/*----------------------------------------------------------------------
rmono - read audio in mono, 16 bit signed integer, little-endian

___Name___Type______In/Out___Description________________________________
   ifil   char*     In       Name of input file
   s[l]   double*   Out      Buffer of samples
   l      int       In       Length of s
----------------------------------------------------------------------*/
int rmono (char *ifil, double *s, int l)
{
/* Local variables */
	int c, j, pos;
	int16_t sampl;
	FILE *iou;
/* Open input file */
	iou = fopen(ifil, "rb");
	if (NULL == iou) {
		printf("trouble opening file: %s\n", ifil);
		return -1;
	}
/* Read in samples, 16 bit signed integer, little-endian, 1 channel */
	pos = 0;
	for (j = 0; j < l; ++j) {  /* for each time */
		++pos;
		c = fgetc(iou);
		if (EOF == c) {
			printf("trouble reading byte %i of %s\n", pos, ifil);
			return 1;
		}
		sampl = c & 255;
		++pos;
		c = fgetc(iou);
		if (EOF == c) {
			printf("trouble reading byte %i of %s\n", pos, ifil);
			return 2;
		}
		sampl |= (c & 255) << 8;
		s[j] = (double) sampl / 32768.;
	}
/* Done with input file */
	c = fclose(iou);
	if (0 != c) {
		printf("trouble closing file: %s\n", ifil);
		return 3;
	}
	return 0;
} /* end of rmono */

/*----------------------------------------------------------------------
wmono - write a raw audio file, 16 bit integer, little-endian, mono

___Name___Type______In/Out___Description________________________________
   ofil   char*     In       Name of output file
   s[l]   double*   In       Buffer of samples
   l      int       In       Length of s
----------------------------------------------------------------------*/
int wmono (char *ofil, double *s, int l)
{
/* Local variables */
	int c, i, j, pos;
	int16_t sampl;
	FILE *iou;
/* Open output file */
	iou = fopen(ofil, "r");
	if (NULL != iou) {
		printf("file exists: %s\n", ofil);
		fclose(iou);
		return 1;
	}
	iou = fopen(ofil, "wb");
	if (NULL == iou) {
		printf("trouble opening output file!\n");
		return 2;
	}
/* Write out samples, 16 bit signed integer, little-endian */
	pos = 0;
	for (j = 0; j < l; ++j) {  /* for each time */
		i = lround(s[j] * 32768.);
		if (i > +32767) i = +32767;
		if (i < -32768) i = -32768;
		sampl = (int16_t) i;
		++pos;
		c = sampl & 255;
		c = fputc(c, iou);
		if (EOF == c) {
			printf("trouble writing byte %i of %s\n", pos, ofil);
			return 3;
		}
		++pos;
		c = (sampl & 65280) >> 8;
		c = fputc(c, iou);
		if (EOF == c) {
			printf("trouble writing byte %i of %s\n", pos, ofil);
			return 4;
		}
	}
	c = fclose(iou);
	if (0 != c) printf("trouble closing file: %s\n", ofil);
	return 0;
} /* end of wmono */
