
#include <stdlib.h>
#include <stdio.h>
#include <inttypes.h>
#include <math.h>

int main(int argc, char *argv[])
{
  FILE *in, *out;
  int src_len;
  char repeats_to_play;
  char base_note;
  int frequency;
  int data_length;
  double *samples;
  int input;
  unsigned short v;
  int i;
  unsigned long filesize;
  double minimum,maximum,scale,middle;
  double result;
  int e;
  unsigned long int m;
  int n;

  if (argc != 3)
  {
    printf("\nSyntax: snd2aiff <src> <dest>\n\n");
    exit(1);
  }

  in = fopen(argv[1], "r");
  src_len = ((int)fgetc(in) << 8) | fgetc(in);
  repeats_to_play = (int)fgetc(in);
  base_note = (int)fgetc(in);
  frequency = ((int)fgetc(in) << 8) | fgetc(in);
  fseek(in, 2, SEEK_CUR);
  data_length = ((int)fgetc(in) << 8) | fgetc(in);

  printf("len:%d, repeats:%d, basenote:%d, freq:%d, datlen:%d\n",
      src_len, repeats_to_play, base_note, frequency, data_length);

  samples = malloc(data_length * sizeof(double));
  for (i=0; i<data_length; i++)
  {
    input = (unsigned int)fgetc(in);
    samples[i] = (double)input;
  }
  fclose(in);

  out = fopen(argv[2], "wb");

  filesize = 46 + 2 * data_length;
  fprintf(out,"FORM");
  fputc((filesize & 0xff000000) >> 24, out);
  fputc((filesize & 0xff0000) >> 16, out);
  fputc((filesize & 0xff00) >> 8, out);
  fputc((filesize & 0xff), out);
  fprintf(out,"AIFF");

  fprintf(out,"COMM");
  // Chunksize always 18
  fputc(0,out);
  fputc(0,out);
  fputc(0,out);
  fputc(18,out);

  // 1 Channel
  fputc(0,out);
  fputc(1,out);

  // Number of samples
  fputc((data_length & 0xff000000) >> 24, out);
  fputc((data_length & 0xff0000) >> 16, out);
  fputc((data_length & 0xff00) >> 8, out);
  fputc((data_length & 0xff), out);

  // Samplesize = 16
  fputc(0,out);
  fputc(16,out);

  result = frexp (frequency , &n);
  e = (((int)n-2) & 0x3fff) | 0x4000;
  fputc((e >> 8), out);
  fputc((e & 0xff), out);

  m = (long int)(result * 0x1000000);
  fputc((m & 0x00ff0000) >> 16,out);
  fputc((m & 0x0000ff00) >> 8,out);
  fputc((m & 0x000000ff),out);
  fputc(0,out);
  fputc(0,out);
  fputc(0,out);
  fputc(0,out);
  fputc(0,out);

  /* Write the sound data chunk */
  fprintf(out,"SSND");
  // Size of sample data
  fputc(((2*data_length+8) & 0xff000000) >> 24, out);
  fputc(((2*data_length+8) & 0xff0000) >> 16, out);
  fputc(((2*data_length+8) & 0xff00) >> 8, out);
  fputc(((2*data_length+8) & 0xff), out);

  // Offset
  fputc(0,out);
  fputc(0,out);
  fputc(0,out);
  fputc(0,out);

  // Block
  fputc(0,out);
  fputc(0,out);
  fputc(0,out);
  fputc(0,out);

  /* Find the range */
  minimum = samples[0];
  maximum = minimum;
  for (i=1; i<data_length; i++)
  {
    if (samples[i] > maximum)
      maximum = samples[i];
    if (samples[i] < minimum)
      minimum = samples[i];
  }

  if (minimum >= maximum)
  {
    minimum -= 1;
    maximum += 1;
  }

  middle = (minimum + maximum) / 2;
  minimum -= middle;
  maximum -= middle;
  if (abs(minimum) > abs(maximum))
    maximum = abs(minimum);
  scale = 32760 / (maximum);

  printf("scale:%lf\n", scale);

  /* Write the data */
  for (i=0;i<data_length;i++) {
    v = (unsigned short)(scale * (samples[i] - middle));
    fputc((v & 0xff00) >> 8,out);
    fputc((v & 0x00ff),out);
  }

  fclose(out);

  return 0;
}

