/************************************************************************/
/* NAME									*/
/*	raw8 - convert Roland 12-bit-sample-disk to raw 8-bit samples	*/
/* SYNOPSIS								*/
/*	raw8 roland-12-bit-sample-disk-file > raw-8-bit-sample-file	*/
/* DESCRIPTION								*/
/*	raw8 converts Roland 12-bit-samples to raw 8-bit samples	*/
/* AUTHOR								*/
/*	Copyright 1992 by Gary J. Murakami <gjm@research.att.com>	*/
/*	V1.0 (4 May 1992) Freely distibutable for non-comercial use.	*/
/*	All other rights reserved.					*/
/*                                                                      */
/*      Spring 1996, modified by Juhana Kouhia <kouhia@nic.funet.fi>    */
/*      to output 16 bit raw data, each sample separately to two files: */
/*      attack part and loop part.                                      */
/************************************************************************/

#include <stdio.h>
#include "rs12.h"

long
uint24(byte * p)
{
        long    i;
        i = *p++;
        i = (i << 8) + *p++;
        i = (i << 8) + *p++;
        return (i);
}

int
sample(byte * p, int si)
{
	int	i, s;

	i = si*3/2;
	if (si % 2) /* odd */
	{	s = (*(p+i+1) & 0x80) ? (-1 << 11) : 0;
		s |= ((*(p+i) & 0x0F) /* << 0 */) | (*(p+i+1) << 4);
	}
	else	/* even */
	{	s = (*(p+i) & 0x80) ? (-1 << 11) : 0;
		s |= ((*(p+i) & 0xFF) << 4) | ((*(p+i+1) & 0xF0) >> 4);
	}
	return (s);
}

int srfreqs[] = {30000,15000};
char *loopmodes[] = {"forward","forward-backward","one-shot","reverse"};

void
convertDisk(Disk * disk)
{
  int	seg, si;
  int s;
  unsigned int us1,us2;
  ToneParameter *tp;
  int i,ii,j,j1,j2,j3,segbegin;
  int *wavea,*waveb,*curwave;
  char fname[20];
  FILE *out;

  wavea = (int *)malloc(18*SamplesPerSegment*3/2*sizeof(int));
  i = 0;
  for (seg = 0; seg < 18; seg ++)
    for (si = 0; si < SamplesPerSegment; si++) {
      wavea[i] = sample(disk->waveDataA[seg].data, si) <<4;
      i++;
    }
  waveb = (int *)malloc(18*SamplesPerSegment*3/2*sizeof(int));
  i = 0;
  for (seg = 0; seg < 18; seg ++)
    for (si = 0; si < SamplesPerSegment; si++) {
      waveb[i] = sample(disk->waveDataB[seg].data, si) <<4;
      i++;
    }

  for (i = 0,ii = 0; i < 32; i++) {
    tp = &disk->toneParameter[i];
    if ((tp->orgSubTone&0x1) == 0) {
      /* suborgs are not original samples */ 
      printf("tone %i:\n",ii+1);
      printf("  name = %8s\n",tp->toneName);
      printf("  sr = %i Hz\n",srfreqs[tp->samplingFrequency&0x1]);
      printf("  loopmode = %s\n",loopmodes[tp->loopMode&0x3]);
      
      segbegin = SamplesPerSegment*tp->waveSegmentTop;
      j1 = segbegin + uint24(tp->startPoint);
      j2 = segbegin + uint24(tp->loopPoint);
      j3 = segbegin + uint24(tp->endPoint);
      if ((tp->waveBank&0x1) == 0) {
	printf("  wavebank A\n");
	curwave = wavea;
      } else {
	printf("  wavebank B\n");
	curwave = waveb;
      }
      printf("  start = %i\n",j1);
      printf("  loop  = %i\n",j2);
      printf("  end   = %i\n",j3);

      (void)sprintf(fname,"%2.2i-a",ii+1);
      out = fopen(fname,"wb");
      for(j = j1; j < j2; j++) {
	us1 = ((unsigned int)curwave[j])&0x000000ff;
	us2 = (((unsigned int)curwave[j])&0x0000ff00)>>8;
	putc((unsigned char)us1, out);
	putc((unsigned char)us2, out);
      }
      fclose(out);

      (void)sprintf(fname,"%2.2i-b",ii+1);
      out = fopen(fname,"wb");
      for(j = j2; j <= j3; j++) {
	us1 = ((unsigned int)curwave[j])&0x000000ff;
	us2 = (((unsigned int)curwave[j])&0x0000ff00)>>8;
	putc((unsigned char)us1, out);
	putc((unsigned char)us2, out);
      }
      fclose(out);
      ii++;
    }
  }
}

Disk	disk;

main(int argc, char ** argv)
{
	int	i;
	FILE *	fin;

	if (argc <= 1)
	{	printf("usage: %s Roland-12-bit-sample-disk-file\n", argv[0]);
		exit(1);
	}
	i = 1;
	if (i < argc)
	{	if ((fin = fopen(argv[i++], "r")) != NULL)
		{	fread(&disk, sizeof(Disk), 1, fin);
			convertDisk(&disk);
			fclose(fin);
		}
		else	printf("%s: open failed for \"%s\"\n", argv[0], argv[i]);
	}
	exit(0);
}
