/* =========================================================================


	SAMPLER.C	Testprogram Falcon Sound Sampling.

				Compiled with Pure C (=Turbo C)

				Parts derived from SNDSCOPE.C.

				R.J. Ridder		13- 4-1993		V 1.00
								21- 4-1993		V 1.02
				W.F. Kilwinger  28- 4-1993      V 1.03


==========================================================================*/

#include <tos.h>
#include <ext.h>

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sndbind.h>

#define SAMPLEFREQ		CLK25K
#define AUDIOSIZE		(clk2freq[SAMPLEFREQ]*2*2*2) /* 2 s 16 bit stereo */
#define BUFFERSIZE		(AUDIOSIZE+1000)		 /* check buffer overflow */

typedef enum { false, true } bool;

char *samplebuffer;
char *buffer_end;
bool memory_present;
long prv_snd_state[7];
int  samplemode;							 /* user input of sample mode */
int  trackmode;    							 /* user input of # of tracks */
long clk2freq[] = { 0, ACT_CLK50K, ACT_CLK33K, ACT_CLK25K, ACT_CLK20K,
					ACT_CLK16K, 0, ACT_CLK12K, 0, ACT_CLK10K, 0, 
					ACT_CLK8K	};



void testfree(void *memory)
{
	if(memory != NULL)  free(memory);
}


void free_all(void)
{
	testfree(samplebuffer);
	memory_present = false;
}


void show_memory(char *text, char *start, int size)
{	int i;

	printf("\n%s%08lX:\n", text, (long)start);
	for(i = 0;  i < size;  i++)
	{	printf("%04X ", ((long*)start)[i]);
		if(i % 16 == 15)  printf("\n");
}	}


void reset_sound_system(void)
{
	sndstatus(1);
	soundcmd(LTATTEN,  prv_snd_state[LTATTEN]);
	soundcmd(RTATTEN,  prv_snd_state[RTATTEN]);
	soundcmd(LTGAIN,   prv_snd_state[LTGAIN]);
	soundcmd(RTGAIN,   prv_snd_state[RTGAIN]);
	soundcmd(ADDERIN,  0x01);
	soundcmd(ADCINPUT, 0x00);
}


bool sample(void)
{	int i;

	if(locksnd() < 0L) 								 /* lock sound system */
	{	printf("[3][Soundsystem blocked][ Quit ]");
		return(false);
	}
	if(memory_present == false)
		samplebuffer = (char*)malloc(AUDIOSIZE);
	if( samplebuffer == NULL )
	{	printf("[3][Not enough memory][ Quit ]");
		free_all();
		unlocksnd();
		return(false);
	}
	else
	{	memory_present = true;
		memset(samplebuffer, 0xAA, BUFFERSIZE);
	}
	for(i = 0;  i < 7;  i++)   	  /* save current sound system parameters */
		prv_snd_state[i] = soundcmd(i, -1);
	reset_sound_system();
	buffer_end = &samplebuffer[AUDIOSIZE];
	settracks(trackmode, trackmode);
	setmontrack(0);
	devconnect(ADC, DMAREC, CLK_25M, SAMPLEFREQ, 1);
	if(buffoper(-1) & 0x04)
		buffoper(0);			           /* clear FIFO conform dev. doc */
	setbuffer(1, (long)samplebuffer, (long)buffer_end);
	setmode(samplemode);
	delay(200);		  /* wait for pulse to settle, don't record the click */
	buffoper(4);	          				/* record enable, single pass */
	do
	{	if(kbhit())	 {	getch();  break;  }	  /* user stopped recording ? */
	} while((buffoper(-1L) & 0x4) != 0); 	 /* check if record is done ? */
	buffoper(0);                           /* make sure recording stopped */
	sndstatus(1);                                   /* reset sound system */
	for(i = 0;  i < 7;  i++)     /* restore saved sound system parameters */
		soundcmd(i, prv_snd_state[i]);
	unlocksnd();                /* make system sound available for others */
	return(true);
}


void replay(void)
{	int i;

	if(locksnd() < 0L)
	{	printf("[3][Soundsystem blocked][ Quit ]");
		return;
	}
	soundcmd(ADDERIN, 0x2 /*MATRIX*/);
	dsptristate(0, 0);
	settracks(trackmode, trackmode);
	setmontrack(0);
	devconnect(DMAPLAY, DAC, CLK_25M, SAMPLEFREQ, 1);
	setbuffer(0, (long)samplebuffer, (long)buffer_end);
	setmode(samplemode);
	buffoper(1);		                      /* play enable, single pass */
	do
	{	if(kbhit())	 {	getch();  break;  }
	} while((buffoper(-1L) & 0x1) != 0);
	buffoper(0);
	sndstatus(1);
	for(i = 0;  i < 7;  i++)
		soundcmd(i, prv_snd_state[i]);
	unlocksnd();
}


int main(void)
{
	printf("Super Simple Sound Sampler...\n");
	printf("Sampling mode [0 = 8bit st, 1 = 16bit st, 2 = 8bit mono]: ");
	scanf("%d", &samplemode);

/* Note that the falcon actually doesn't support 8-bit recording, you have
   to convert the recorded 16-bit data to 8-bit yourself. So, if you select
   8-bit in this example you get horrible sound.                          */

	printf("\nTrack mode [0 = 1 track, 1 = 2 tracks, 2 = 3 tracks, 3 = 4 tracks]: ");
	scanf("%d", &trackmode);

    printf("\n Recording now ....\n\n");
	if(sample())
	{	show_memory("Start address: ", samplebuffer, 160);
		show_memory("Middle buffer: ", samplebuffer + AUDIOSIZE/2, 160);
		show_memory("End check $AA: ", buffer_end, 16);
		printf("\nThis is what I recorded for you ....\n");
        replay();
		printf("That's it !\n");
		free_all();
	}
	printf("\nSound status = %d.\nPress a key...\n", sndstatus(0));  getch();
	return(0);
}

/* ==== Program Text End ================================================ */
