text: #include "wav_amr.h"
  #include <stdio.h>
  #include <stdlib.h>
  #include <string.h>
  #include <stdint.h>
  #include "interf_enc.h"
  #include "interf_dec.h"
  #include "wavreader.h"
  #include "wavwriter.h"
  
  const int sizes[] = { 12, 13, 15, 17, 19, 20, 26, 31, 5, 6, 5, 5, 0, 0, 0, 0 };
  int decode_amr(const char* infile, const char* outfile) {
  	FILE* in = fopen(infile, "rb");
  	if (!in) {
  		return 1;
  	}
  	char header[6];
  	ssize_t n = fread(header, 1, 6, in);
  	if (n != 6 || memcmp(header, "#!AMR\n", 6)) {
  		fprintf(stderr, "Bad header\n");
  		return 1;
  	}
      
      void* wav = wav_write_open(outfile, 8000, 16, 1);
  
  	void* amr = Decoder_Interface_init();
  	while (1) {
  		uint8_t buffer[500];
  		/* Read the mode byte */
  		n = fread(buffer, 1, 1, in);
  		if (n <= 0)
  			break;
  		/* Find the packet size */
  		int size = sizes[(buffer[0] >> 3) & 0x0f];
  		if (size <= 0)
              continue;
  		n = fread(buffer + 1, 1, size, in);
  		if (n != size)
  			break;
  		/* Decode the packet */
  		int16_t outbuffer[160];
  		Decoder_Interface_Decode(amr, buffer, outbuffer, 0);
  		/* Convert to little endian and write to wav */
  		uint8_t littleendian[320];
  		uint8_t* ptr = littleendian;
  		for (int i = 0; i < 160; i++) {
  			*ptr++ = (outbuffer[i] >> 0) & 0xff;
  			*ptr++ = (outbuffer[i] >> 8) & 0xff;
  		}
          wav_write_data(wav, littleendian, 320);
  	}
  	fclose(in);
  	Decoder_Interface_exit(amr);
      wav_write_close(wav);
  	return 0;
  }
  
  int encode_amr(const char* infile, const char* outfile) {
      enum Mode mode = MR122;
      FILE *out;
      void *wav, *amr;
      int format, sampleRate, channels, bitsPerSample;
      int inputSize;
      uint8_t* inputBuf;
  
      wav = wav_read_open(infile);
      if (!wav) {
          fprintf(stderr, "Unable to open wav file %s\n", infile);
          return 1;
      }
      if (!wav_get_header(wav, &format, &channels, &sampleRate, &bitsPerSample, NULL)) {
          fprintf(stderr, "Bad wav file %s\n", infile);
          return 1;
      }
      if (format != 1) {
          fprintf(stderr, "Unsupported WAV format %d\n", format);
          return 1;
      }
      if (bitsPerSample != 16) {
          fprintf(stderr, "Unsupported WAV sample depth %d\n", bitsPerSample);
          return 1;
      }
      if (channels != 1)
          fprintf(stderr, "Warning, only compressing one audio channel\n");
      if (sampleRate != 8000)
          fprintf(stderr, "Warning, AMR-NB uses 8000 Hz sample rate (WAV file has %d Hz)\n", sampleRate);
      
      inputSize = channels*2*160;
      inputBuf = (uint8_t*) malloc(inputSize);
      
      amr = Encoder_Interface_init(0);
      out = fopen(outfile, "wb");
      if (!out) {
          perror(outfile);
          return 1;
      }
      
      fwrite("#!AMR\n", 1, 6, out);
      while (1) {
          short buf[160];
          uint8_t outbuf[500];
          int read, i, n;
          read = wav_read_data(wav, inputBuf, inputSize);
          read /= channels;
          read /= 2;
          if (read < 160)
              break;
          for (i = 0; i < 160; i++) {
              const uint8_t* in = &inputBuf[2*channels*i];
              buf[i] = in[0] | (in[1] << 8);
          }
          n = Encoder_Interface_Encode(amr, mode, buf, outbuf, 0);
          fwrite(outbuf, 1, n, out);
      }
      free(inputBuf);
      fclose(out);
      Encoder_Interface_exit(amr);
      wav_read_close(wav);
      
      return 0;
  }
  
  