
/*
 * S770 sample-extracter, Copyright 1996 Juhana Kouhia.
 * Juhana Kouhia, kouhia@nic.funet.fi
 */

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



FILE *in, *out;
int g;
int bufi[256];
int bufc[256];

int sd[40][32];

void pn(n)
int n;
{
  int i;
  int c;

  for(i = 0; i < n; i++) {
    c = getc(in);
    g++;
    fprintf(stderr,"%i ",c);
  }
  fprintf(stderr,"\n");
}

void pnsd(n,m)
int n,m;
{
  int i;
  int c;

  for(i = 0; i < n; i++) {
    c = getc(in);
    g++;
    sd[m][i] = c;
    if (i == 16) fprintf(stderr,"\n");
    fprintf(stderr,"%i ",c);
  }
  fprintf(stderr,"\n");
}

void pc(n)
int n;
{
  int i;
  int c;

  for(i = 0; i < n; i++) {
    c = getc(in);
    g++;
    fprintf(stderr,"%c",c);
  }
  fprintf(stderr,"\n");
}

void ps(n)
int n;
{
  int i;
  int c;

  for(i = 0; i < n; i++) {
    c = getc(in);
    g++;
  }
  fprintf(stderr,"skipped %i bytes\n",n);
}

void pu(n)
int n;
{
  int i;
  int c;

  i = 0;
  while (g < n) {
    c = getc(in);
    g++;
    i++;
  }
  fprintf(stderr,"skipped %i bytes up to %i\n",i,n);
}

int onepi()
{
  fread(bufi,sizeof(int),1,in);
  g += sizeof(int);
  return(bufi[0]);
}

void pi(n)
int n;
{
  int i;

  for(i = 0; i < n; i++) {
    fprintf(stderr,"%i ",onepi());
  }
  fprintf(stderr,"\n");
}

int onepadd()
{
  int c,n;

  n = 0;
  c = getc(in);
  c = getc(in);
  n += c;
  c = getc(in);
  n += 256*c;
  c = getc(in);
  n += (256^2)*c;
  g += 4;
  return(n);
}

void padd(n)
int n;
{
  int i;

  for(i = 0; i < n; i++) {
    fprintf(stderr,"%i ",onepadd());
  }
  fprintf(stderr,"\n");
}

int onehtoi(ch)
char ch;
{
  if (ch == '0') return(0);
  if (ch == '1') return(1);
  if (ch == '2') return(2);
  if (ch == '3') return(3);
  if (ch == '4') return(4);
  if (ch == '5') return(5);
  if (ch == '6') return(6);
  if (ch == '7') return(7);
  if (ch == '8') return(8);
  if (ch == '9') return(9);
  if (ch == 'a') return(10);
  if (ch == 'b') return(11);
  if (ch == 'c') return(12);
  if (ch == 'd') return(13);
  if (ch == 'e') return(14);
  if (ch == 'f') return(15);
}

int htoi(s)
char *s;
{
  int i;
  int x;

  x = onehtoi(s[0]);
  if ((int)strlen(s) == 1) return(x);
  for(i = 1; i < (int)strlen(s); i++) {
    x = 16*x + onehtoi(s[i]);
  }
  return(x);
}

void puh(s)
char *s;
{
  pu(htoi(s));
}

void searchname()
{
  int c,i;
  char s[17];

  for(i = 0; i < 16; i++) s[i] = ' ';
  s[16] = '\0';

  i = 0;
  while (i < 16) {
    c = getc(in);
    g++;
    if (c == EOF) {
      fprintf(stderr,"no name found due EOF\n");
      exit(-1);
    }
    if ((32 <= c) && (c <= 126)) {
      s[i] = (char)c;
      i++;
    } else {
      i = 0;
    }
  }
  fprintf(stderr,"%s  at %i\n",s,g-16);
}

void filew(m,n)
int m,n;
{
  char fname[20];
  unsigned char *b,*bb,*b2;
  int i,i1,i2,i3,i4,i5,nn,nn2;

  b = (unsigned char *)malloc(n*sizeof(unsigned char));
  (void)fread(b,sizeof(unsigned char),n,in);
  g += n;

  i1 = sd[m][1] + 256*sd[m][2] + 256*256*sd[m][3];
  i2 = sd[m][5] + 256*sd[m][6] + 256*256*sd[m][7];
  i3 = sd[m][9] + 256*sd[m][10] + 256*256*sd[m][11];
  i4 = sd[m][13] + 256*sd[m][14] + 256*256*sd[m][15];
  i5 = sd[m][17] + 256*sd[m][18] + 256*256*sd[m][19];
  i1 *= 2;
  i2 *= 2;
  i3 *= 2;
  i4 *= 2;
  i5 *= 2;
  fprintf(stderr,"%i %i %i %i %i -- %i\n",i1,i2,i3,i4,i5,n);

  (void)sprintf(fname,"%2.2i-a",m+1);
  out = fopen(fname,"w");
  nn = i2-i1+2;
  bb = &b[i1];
  if ((nn2 = fwrite(bb,sizeof(unsigned char),nn,out)) != nn) {
    fprintf(stderr,"write error\n");
    exit(-1);
  }
  fclose(out);

  (void)sprintf(fname,"%2.2i-b",m+1);
  out = fopen(fname,"w");
  nn = i3-i2+2;
  bb = &b[i2];
  if ((nn2 = fwrite(bb,sizeof(unsigned char),nn,out)) != nn) {
    fprintf(stderr,"write error\n");
    exit(-1);
  }
  fclose(out);

  if (sd[m][20] == 4) {
    b2 = (unsigned char *)malloc(nn*sizeof(unsigned char));
    for(i = 0; i < nn; i += 2) {
      b2[i] = bb[nn-i-2];
      b2[i+1] = bb[nn-i-1];
    }
    (void)sprintf(fname,"%2.2i-bb",m+1);
    out = fopen(fname,"w");
    if ((nn2 = fwrite(b2,sizeof(unsigned char),nn,out)) != nn) {
      fprintf(stderr,"write error\n");
      exit(-1);
    }
    free(b2);
    fclose(out);
  }

  if (i4 <= n) {
    (void)sprintf(fname,"%2.2i-c",m+1);
    out = fopen(fname,"w");
    nn = i4-i3+2;
    bb = &b[i3];
    if ((nn2 = fwrite(bb,sizeof(unsigned char),nn,out)) != nn) {
      fprintf(stderr,"write error\n");
      exit(-1);
    }
    fclose(out);
  }

  free(b);
}


main(ac,av)
int ac;
char **av;
{
  int i,j,diskno,samples;
  unsigned char *sfile;

  char fname[128];
  int m,n,o,p,i1,i2,d2;

  g = 0;

  if (ac <= 1) {
    fprintf(stderr,"Usage: s770toraw <samplefile>\n");
    exit(-1);
  } else if (ac <= 2) {
    if ((in = fopen(av[1],"r")) == NULL) {
      fprintf(stderr,"%s: could not open the file %s\n",av[0],av[1]);
      exit(-1);
    }
  } else {
    fprintf(stderr,"Usage: s770toraw <samplefile>\n");
    exit(-1);
  }

/*  (void)fseek(in,(long)0,SEEK_END);
  buflen = ftell(in);
  (void)fseek(in,(long)0,SEEK_SET);
  sfile = (unsigned char *)malloc(buflen*sizeof(unsigned char));
  i = fread(sfile,sizeof(unsigned char),buflen,in);
  if (i != buflen) {
    fprintf(stderr,"%s: could not read the file %s\n",av[0],av[1]);
    exit(-1);
  }
  fclose(in);
*/
/*  g = 101888;
  */

  pn(4);
  pc(10);
  pn(2);
/*
  puh("180"); / * 384 * /
  pc(16);
*/
/*
  for(i = 0; i < 400; i++) {
    searchname();
  }
exit(0);
*/
  pc(16);
  pc(16);
  pc(16);
  pc(16);
  pc(16);

  ps(16*10);
  fprintf(stderr,"loc = %i\n",g);
  diskno = getc(in);
  g++;
  fprintf(stderr,"disk no = %i\n",diskno);
  pn(13);
  samples = getc(in);
  g++;
  fprintf(stderr,"samples = %i\n",samples);
  pn(3);
  ps(16*6+14);
  fprintf(stderr,"loc = %i\n",g);
  pc(16);
  pn(17);
  ps(16*5+15);
  fprintf(stderr,"loc = %i\n",g);
  pn(2);
  ps(16*45+16*18+14);
  fprintf(stderr,"loc = %i\n",g);
  pn(14);
  ps(16*45+16*18+2);
  fprintf(stderr,"loc = %i\n",g);
  pn(16);
  pn(16);
  pn(4);
  ps(16*61+12);
  fprintf(stderr,"loc = %i\n",g);
  pn(16);
  pn(16);
  pn(4);
  ps(16*61+12);
  fprintf(stderr,"loc = %i\n",g);
  pc(16);
  ps(16*63);
  fprintf(stderr,"loc = %i\n",g);
  pc(16);
  pc(16);
  pc(16);
  pc(16);
  pc(16);
  pc(16);
  pc(16);
  ps(16*121);
  fprintf(stderr,"loc = %i\n",g);
  for(i = 0; i < 18; i++) pc(16);
  ps(16*238);
  fprintf(stderr,"loc = %i\n",g);
  for(i = 0; i < 18; i++) pc(16);
  ps(16*494);
  fprintf(stderr,"loc = %i\n",g);
  pc(16);
  for(i = 0; i < 14; i++) pn(16);
  ps(16*17);
  fprintf(stderr,"loc = %i\n",g);
  ps(16*992);
  fprintf(stderr,"loc = %i\n",g);
  pc(16);
  for(i = 0; i < 15; i++) pn(16);
  fprintf(stderr,"loc = %i\n",g);
  pc(16);
  for(i = 0; i < 15; i++) pn(16);
  fprintf(stderr,"loc = %i\n",g);
  pc(16);
  for(i = 0; i < 15; i++) pn(16);
  fprintf(stderr,"loc = %i\n",g);
  pc(16);
  for(i = 0; i < 15; i++) pn(16);
  fprintf(stderr,"loc = %i\n",g);
  pc(16);
  for(i = 0; i < 15; i++) pn(16);
  fprintf(stderr,"loc = %i\n",g);
  pc(16);
  for(i = 0; i < 15; i++) pn(16);
  fprintf(stderr,"loc = %i\n",g);
  pc(16);
  for(i = 0; i < 15; i++) pn(16);
  fprintf(stderr,"loc = %i\n",g);
  pc(16);
  for(i = 0; i < 15; i++) pn(16);
  fprintf(stderr,"loc = %i\n",g);
  ps(16*1500+16*420);
  fprintf(stderr,"loc = %i\n",g);
  for(j = 0; j < 32; j++) {
    pc(16);
    for(i = 0; i < 7; i++) pn(16);
    fprintf(stderr,"loc = %i\n",g);
  }
/*  ps(16*1888); */
  pu(101888);
  fprintf(stderr,"loc = %i\n",g);
  for(j = 0; j < samples; j++) {
    if ((j == 10) || (j == 20)) for(i = 0; i < 2; i++) pn(16);
    pc(16);
    pnsd(32,j);
    fprintf(stderr,"loc = %i\n",g);
  }
/*  ps(16*1632); */
  pu(129024);
  fprintf(stderr,"loc = %i\n",g);
  fprintf(stderr,"sample data starts here\n");


  /*
   * sample table, 48 bytes each entry, starting from 101888 = 18e00
   *
   *
   * 706_3: seqtop >= 5, not seqtop >= 0 as in other file
   * 709_1 & 709_2: same header data except in loc 256 (== 0 & 1, file number)
   * how to know how many samples are in the file? seqtop < 160?
   * if seqtop changes down, then change file...? Is seqtop's second
   * number a disk no?
   *
   * loop modes:
   *     0 == no loop
   *     2 == forward
   *     4 == forward-backward
   */

  d2 = 100;
  for(i = 0; i < samples; i++) {
    if (sd[i][25] == 1) if (d2 > i) d2 = i;
  }
  if (d2 == 100) d2 = samples;
  i1 = 0;
  i2 = d2;
  if (diskno == 1) {
    i1 = d2;
    i2 = samples;
  }

  for(i = i1; i < i2; i++) {
    fprintf(stderr,"begin i = %i\n",i);
    m = sd[i][24]; /* + 256*sd[i][25];     item 25 is 1 ?= disk no */
    if (i == i1) ps(m*18*512);
    n = sd[i][26] + 256*sd[i][27];
    fprintf(stderr,"seg = %i %i\n",m,n);
    filew(i,n*18*512);
    fprintf(stderr,"end i = %i\n",i);
  }

}
