/* This demo is supposed to be fed with a 16 bit raw format soundfile
 * with the least significant byte first.
 * It is able to give the Amiga 14 bit sound instead of the normal 8
 * by combining channels.
 By David Ekholm
 */

#include <exec/types.h>
#include <stdio.h>
#include <dos.h>
#include <exec/memory.h>
#include <hardware/custom.h>
#include <hardware/dmabits.h>
#include <proto/exec.h>

#define SOUNDLENGTH 128000
/* Defines how much chip mem is to be allocated for each channel. */

struct Custom *custom = (struct Custom *)0xDFF000;
/* Now we've got access to all hardware registers in a nice manner */

void PrintHelp(argv)
char *argv[];
{
	printf("USAGE: %s <16bit data file> <period (124 is the fastest)>\n\n"
		,argv[0]);
	printf("This program plays soundfiles in 14 bit resolution!!!\n");
	printf("Use the joystick button to toggle 14/8 bit sound\n");
	printf("and the left mousebutton to quit\n");
	printf("Programmed by David Ekholm\n\n");
}

void main(argc, argv)
int argc;
char *argv[];
{
	FILE *fp;
	BYTE *soundpointer[2] = {NULL, NULL};
	int per, tempdata;
	USHORT period;
	int count0 = 0,count1 = 0, i;
	BYTE data;
	BOOL odd = 0,toggle = 0;
	
	/******************** Input handling *********************/
	if (argc != 3) { PrintHelp(argv); exit(FALSE); }
	if (stcd_i(argv[2],&per) == NULL) { PrintHelp(argv); exit(FALSE); }
	period = per;
	
	if ((fp = fopen(argv[1],"rb")) == NULL) {
		printf("Couldn't open '%s' for input\n",argv[1]);
		exit(FALSE);
	}
	 
	if ((soundpointer[0] = (BYTE *)
	 AllocMem(SOUNDLENGTH, MEMF_CHIP)) == NULL) {
		printf("Not enough memory for 8 bit sound buffer\n"); exit(FALSE);
	}

	if ((soundpointer[1] = (BYTE *)
	 AllocMem(SOUNDLENGTH, MEMF_CHIP)) == NULL) {
		printf("Not enough memory for 6 bit sound buffer\n");
		FreeMem(soundpointer[0],SOUNDLENGTH); exit(FALSE);
	}
	
	/******************** Data fetching **********************/
	
	while ((tempdata = getc(fp)) != EOF && count0 < SOUNDLENGTH) {
		data = tempdata;
		if (odd == 0) {
			data = ((data >> 2) & 63)^128;
			*(soundpointer[1]+count0) = data;
			count0++;
		}
		else { 
			*(soundpointer[0]+count1) = data;
			count1++;
		} 
		odd ^= 1;
	}
	
	/******************** Let's play it *******************/
	
	custom->dmacon = DMAF_AUD0 | DMAF_AUD1 | DMAF_AUD2 | DMAF_AUD3;
	
	custom->aud[0].ac_ptr = (UWORD *)soundpointer[0];
	custom->aud[0].ac_len = count0>>1;
	custom->aud[0].ac_per = period;
	custom->aud[0].ac_vol = 63;

	custom->aud[1].ac_ptr = (UWORD *)soundpointer[0];
	custom->aud[1].ac_len = count0>>1;
	custom->aud[1].ac_per = period;
	custom->aud[1].ac_vol = 63;

	custom->aud[2].ac_ptr = (UWORD *)soundpointer[1];
	custom->aud[2].ac_len = count1>>1;
	custom->aud[2].ac_per = period;
	custom->aud[2].ac_vol = 1;

	custom->aud[3].ac_ptr = (UWORD *)soundpointer[1];
	custom->aud[3].ac_len = count1>>1;
	custom->aud[3].ac_per = period;
	custom->aud[3].ac_vol = 1;
	
	custom->dmacon = DMAF_SETCLR | DMAF_AUD0 | DMAF_AUD1 | DMAF_AUD2 
	| DMAF_AUD3;
	
	*(char *)0xBFE001 |= 2;
	
	while(*(char *)0xBFE001 & 64) {
		if (!(*(char *)0xBFE001 & 128)) {
			custom->aud[3].ac_vol = custom->aud[2].ac_vol = toggle==0 ? 0 : 1;
			printf("Now we've got %d bits!!!\n",toggle == 0 ? 8 : 14);
			toggle = !toggle;
			Delay(10);
		}
		Delay(5);
	}

	*(char *)0xBFE001 &= ~2;
	custom->dmacon = DMAF_AUD0 | DMAF_AUD1 | DMAF_AUD2 | DMAF_AUD3;
	
	FreeMem(soundpointer[0], SOUNDLENGTH);
	FreeMem(soundpointer[1], SOUNDLENGTH);
}
 



