home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
AmigActive 6
/
AACD06.ISO
/
AACD
/
Emulation
/
Atari800
/
nas.c
< prev
next >
Wrap
C/C++ Source or Header
|
1997-10-01
|
6KB
|
264 lines
#include <stdio.h>
#include <audio/audiolib.h>
static char *rcsid = "$Id: nas.c,v 1.4 1996/10/09 21:09:06 david Exp $";
#define FALSE 0
#define TRUE 1
#define SAMPLE_RATE 8000
static nasbug = FALSE; /* Debug Flag */
static sound_enabled = FALSE;
static AuServer *au_server;
static AuDeviceID *au_device;
static AuFlowID au_channel[4];
static int waveform = AuWaveFormSquare;
static int au_channel_clock[4] = { 64000, 64000, 64000, 64000 };
static int M[4] = { 1, 1, 1, 1 };
static int AUDCTL = 0x00;
static int AUDF[4] = { 0, 0, 0, 0 };
static int AUDC[4] = { 0, 0, 0, 0 };
void NAS_Initialise (int *argc, char *argv[])
{
int i, j;
for (i=j=1;i<*argc;i++)
{
if (strcmp(argv[i],"-sound") == 0)
sound_enabled = TRUE;
else if (strcmp(argv[i],"-squarewave") == 0)
waveform = AuWaveFormSquare;
else if (strcmp(argv[i],"-sinewave") == 0)
waveform = AuWaveFormSine;
else if (strcmp(argv[i],"-nasbug") == 0)
nasbug = TRUE;
else
{
if (strcmp(argv[i],"-help") == 0)
{
printf ("\t-sound Enable NAS sound support\n");
printf ("\t-squarewave Generate sound with a square wave\n");
printf ("\t-sinewave Generate sound with a sine wave\n");
printf ("\t-nasbug Enable debug code in nas.c\n");
}
argv[j++] = argv[i];
}
}
*argc = j;
if (sound_enabled)
{
au_server = AuOpenServer (NULL, 0, NULL, 0, NULL, NULL);
if (!au_server)
{
printf ("Unable to open audio server\n");
exit (1);
}
for (au_device=NULL,i=0;i<AuServerNumDevices(au_server);i++)
{
if ((AuDeviceKind(AuServerDevice(au_server,i)) ==
AuComponentKindPhysicalOutput) &&
AuDeviceNumTracks(AuServerDevice(au_server,i)) == 1)
{
au_device = (AuDeviceID*)AuDeviceIdentifier(AuServerDevice(au_server,i));
break;
}
}
au_channel[0] = AuCreateFlow (au_server, NULL);
au_channel[1] = AuCreateFlow (au_server, NULL);
au_channel[2] = AuCreateFlow (au_server, NULL);
au_channel[3] = AuCreateFlow (au_server, NULL);
for (i=0;i<4;i++)
{
AuElement elements[3];
int freq = 0;
int volume = AuFixedPointFromFraction(0,100);
AuMakeElementImportWaveForm (&elements[0], SAMPLE_RATE,
waveform,
AuUnlimitedSamples,
freq,
0, NULL);
AuMakeElementMultiplyConstant (&elements[1], 0, volume);
AuMakeElementExportDevice (&elements[2], 1, (int)au_device, SAMPLE_RATE,
AuUnlimitedSamples, 0, NULL);
AuSetElements (au_server, au_channel[i], AuTrue, 3, elements, NULL);
AuStartFlow (au_server, au_channel[i], NULL);
}
}
}
void NAS_Exit (void)
{
if (sound_enabled)
{
int i;
for (i=0;i<4;i++)
{
AuStopFlow (au_server, au_channel[i], NULL);
}
AuCloseServer (au_server);
}
}
void NAS_SetFrequency (int channel, int frequency)
{
if (frequency < 8000)
{
static AuElementParameters parms;
parms.flow = channel;
parms.element_num = 0;
parms.num_parameters = AuParmsImportWaveForm;
parms.parameters[AuParmsImportWaveFormFrequency] = frequency;
parms.parameters[AuParmsImportWaveFormNumSamples] = AuUnlimitedSamples;
AuSetElementParameters (au_server, 1, &parms, NULL);
}
}
void NAS_SetVolume (int channel, int volume)
{
static AuElementParameters parms;
parms.flow = channel;
parms.element_num = 1;
parms.num_parameters = AuParmsMultiplyConstant;
parms.parameters[AuParmsMultiplyConstantConstant] = volume;
AuSetElementParameters (au_server, 1, &parms, NULL);
}
static int join12 = FALSE;
static int join34 = FALSE;
void NAS_UpdateSound (void)
{
if (sound_enabled)
{
int i;
for (i=0;i<4;i++)
{
int freqtmp;
int flag = FALSE;
if ((i < 2) && join12)
{
if (i == 1)
{
int N = ((AUDF[1] << 8) | AUDF[0]) + M[0];
if (nasbug)
printf ("join12: N=%d\n", N);
freqtmp = au_channel_clock[0] / (N + N);
flag = TRUE;
}
}
else if ((i >= 2) && join34)
{
if (i == 3)
{
int N = ((AUDF[3] << 8) | AUDF[2]) + M[2];
if (nasbug)
printf ("join34: N=%d\n", N);
freqtmp = au_channel_clock[2] / (N + N);
flag = TRUE;
}
}
else
{
int N = AUDF[i] + M[i];
freqtmp = au_channel_clock[i] / (N + N);
flag = TRUE;
}
if (flag)
{
int distortion = AUDC[i] & 0xf0;
int voltmp;
if ((distortion == 0xa0) || (distortion == 0xd0))
voltmp = AuFixedPointFromFraction ((AUDC[i] & 0x0f), 30);
else
voltmp = AuFixedPointFromFraction (0, 30);
NAS_SetFrequency (au_channel[i], freqtmp);
NAS_SetVolume (au_channel[i], voltmp);
}
}
AuFlush (au_server);
}
}
void Atari_AUDC (int channel, int byte)
{
AUDC[channel-1] = byte;
}
void Atari_AUDF (int channel, int byte)
{
AUDF[channel-1] = byte;
}
void Atari_AUDCTL (int byte)
{
AUDCTL = byte;
if (byte & 0x01)
{
au_channel_clock[0] = 15000;
au_channel_clock[1] = 15000;
au_channel_clock[2] = 15000;
au_channel_clock[3] = 15000;
}
else
{
au_channel_clock[0] = 64000;
au_channel_clock[1] = 64000;
au_channel_clock[2] = 64000;
au_channel_clock[3] = 64000;
}
M[0] = M[1] = M[2] = M[3] = 1;
join34 = (byte & 0x08) ? TRUE : FALSE; /* Clock channel 4 with channel 3 */
join12 = (byte & 0x10) ? TRUE : FALSE; /* Clock channel 2 with channel 1 */
if (byte & 0x20)
{
au_channel_clock[2] = 1790000; /* Clock channel 3 with 1.79 MHZ */
M[2] = (join34) ? 7 : 4;
}
if (byte & 0x40)
{
au_channel_clock[0] = 1790000; /* Clock channel 1 with 1.79 MHZ */
M[0] = (join12) ? 7 : 4;
}
if (nasbug && (byte & 0xfe))
printf ("AUDCTL: %02x\n", byte);
}