Genesis-Plus-GX/source/unused/dos/SEALINTF.C

289 lines
7.9 KiB
C++
Raw Normal View History

2008-08-07 14:26:07 +02:00
#include "osd.h"
int seal_sample_rate = 44100;
int seal_sound_card = -1;
HAC hVoice[NUMVOICES];
LPAUDIOWAVE lpWave[NUMVOICES];
AUDIOINFO info;
AUDIOCAPS caps;
int c[MAX_STREAM_CHANNELS];
int nominal_sample_rate;
static int attenuation = 0;
static int master_volume = 256;
void osd_update_audio(void)
{
if (seal_sample_rate == 0) return;
AUpdateAudio();
}
/* attenuation in dB */
void osd_set_mastervolume(int _attenuation)
{
float volume;
attenuation = _attenuation;
volume = 256.0; /* range is 0-256 */
while (_attenuation++ < 0)
volume /= 1.122018454; /* = (10 ^ (1/20)) = 1dB */
master_volume = volume;
ASetAudioMixerValue(AUDIO_MIXER_MASTER_VOLUME,master_volume);
}
int msdos_init_sound(int *rate, int card)
{
int i;
seal_sample_rate = *rate;
seal_sound_card = card;
if (AInitialize() != AUDIO_ERROR_NONE)
return 1;
/* Ask the user if no sound card was chosen */
if (seal_sound_card == -1)
{
unsigned int k;
printf("\n SELECT YOUR AUDIO DEVICE :\n\n"
" AWE32/64 playback requires onboard DRAM,\n"
" Sound Blaster playback is the most compatible & better for emulation\n\n");
for (k = 0;k < AGetAudioNumDevs();k++)
{
if (AGetAudioDevCaps(k,&caps) == AUDIO_ERROR_NONE)
printf(" %2d. %s\n",k,caps.szProductName);
}
printf("\n");
if (k < 10)
{
i = getch();
seal_sound_card = i - '0';
}
else
scanf("%d",&seal_sound_card);
}
/* initialize SEAL audio library */
if (seal_sound_card == 0) /* silence */
{
/* update the Machine structure to show that sound is disabled */
seal_sample_rate = 0;
exit(0);
return 0;
}
/* open audio device */
/* info.nDeviceId = AUDIO_DEVICE_MAPPER;*/
info.nDeviceId = seal_sound_card;
/* always use 16 bit mixing if possible - better quality and same speed of 8 bit */
info.wFormat = AUDIO_FORMAT_16BITS | AUDIO_FORMAT_STEREO | AUDIO_FORMAT_RAW_SAMPLE;
info.nSampleRate = seal_sample_rate;
if (AOpenAudio(&info) != AUDIO_ERROR_NONE)
{
return (1);
}
AGetAudioDevCaps(info.nDeviceId,&caps);
printf("Using `%s' at %d-bit %s %u Hz\n",
caps.szProductName,
info.wFormat & AUDIO_FORMAT_16BITS ? 16 : 8,
info.wFormat & AUDIO_FORMAT_STEREO ? "stereo" : "mono",
info.nSampleRate);
/* open and allocate voices, allocate waveforms */
if (AOpenVoices(NUMVOICES) != AUDIO_ERROR_NONE)
{
printf("voices initialization failed\n");
return 1;
}
for (i = 0; i < NUMVOICES; i++)
{
if (ACreateAudioVoice(&hVoice[i]) != AUDIO_ERROR_NONE)
{
printf("voice #%d creation failed\n",i);
return 1;
}
ASetVoicePanning(hVoice[i],128);
lpWave[i] = 0;
}
/* update the Machine structure to reflect the actual sample rate */
*rate = seal_sample_rate = info.nSampleRate;
{
uclock_t a,b;
LONG start,end;
if ((lpWave[0] = (LPAUDIOWAVE)malloc(sizeof(AUDIOWAVE))) == 0)
return 1;
lpWave[0]->wFormat = AUDIO_FORMAT_8BITS | AUDIO_FORMAT_MONO;
lpWave[0]->nSampleRate = seal_sample_rate;
lpWave[0]->dwLength = 3*seal_sample_rate;
lpWave[0]->dwLoopStart = 0;
lpWave[0]->dwLoopEnd = 3*seal_sample_rate;
if (ACreateAudioData(lpWave[0]) != AUDIO_ERROR_NONE)
{
free(lpWave[0]);
lpWave[0] = 0;
return 1;
}
memset(lpWave[0]->lpData,0,3*seal_sample_rate);
/* upload the data to the audio DRAM local memory */
AWriteAudioData(lpWave[0],0,3*seal_sample_rate);
APrimeVoice(hVoice[0],lpWave[0]);
ASetVoiceFrequency(hVoice[0],seal_sample_rate);
ASetVoiceVolume(hVoice[0],0);
AStartVoice(hVoice[0]);
a = uclock();
/* wait some time to let everything stabilize */
do
{
osd_update_audio();
b = uclock();
} while (b-a < UCLOCKS_PER_SEC/10);
a = uclock();
AGetVoicePosition(hVoice[0],&start);
do
{
osd_update_audio();
b = uclock();
} while (b-a < UCLOCKS_PER_SEC);
AGetVoicePosition(hVoice[0],&end);
nominal_sample_rate = seal_sample_rate;
seal_sample_rate = end - start;
AStopVoice(hVoice[0]);
ADestroyAudioData(lpWave[0]);
free(lpWave[0]);
lpWave[0] = 0;
}
osd_set_mastervolume(0); /* start at maximum volume */
return 0;
}
void msdos_shutdown_sound(void)
{
if (seal_sample_rate != 0)
{
int n;
/* stop and release voices */
for (n = 0; n < NUMVOICES; n++)
{
AStopVoice(hVoice[n]);
ADestroyAudioVoice(hVoice[n]);
if (lpWave[n])
{
ADestroyAudioData(lpWave[n]);
free(lpWave[n]);
lpWave[n] = 0;
}
}
ACloseVoices();
ACloseAudio();
}
}
void playstreamedsample(int channel,signed char *data,int len,int freq,int volume,int pan,int bits)
{
static int playing[NUMVOICES];
static int c[NUMVOICES];
/* backwards compatibility with old 0-255 volume range */
if (volume > 100) volume = volume * 25 / 255;
if (seal_sample_rate == 0 || channel >= NUMVOICES) return;
if (!playing[channel])
{
if (lpWave[channel])
{
AStopVoice(hVoice[channel]);
ADestroyAudioData(lpWave[channel]);
free(lpWave[channel]);
lpWave[channel] = 0;
}
if ((lpWave[channel] = (LPAUDIOWAVE)malloc(sizeof(AUDIOWAVE))) == 0)
return;
lpWave[channel]->wFormat = (bits == 8 ? AUDIO_FORMAT_8BITS : AUDIO_FORMAT_16BITS)
| AUDIO_FORMAT_MONO | AUDIO_FORMAT_LOOP;
lpWave[channel]->nSampleRate = nominal_sample_rate;
lpWave[channel]->dwLength = 3*len;
lpWave[channel]->dwLoopStart = 0;
lpWave[channel]->dwLoopEnd = 3*len;
if (ACreateAudioData(lpWave[channel]) != AUDIO_ERROR_NONE)
{
free(lpWave[channel]);
lpWave[channel] = 0;
return;
}
memset(lpWave[channel]->lpData,0,3*len);
memcpy(lpWave[channel]->lpData,data,len);
/* upload the data to the audio DRAM local memory */
AWriteAudioData(lpWave[channel],0,3*len);
APrimeVoice(hVoice[channel],lpWave[channel]);
/* need to cast to double because freq*nominal_sample_rate can exceed the size of an int */
ASetVoiceFrequency(hVoice[channel],(double)freq*nominal_sample_rate/seal_sample_rate);
AStartVoice(hVoice[channel]);
playing[channel] = 1;
c[channel] = 1;
}
else
{
LONG pos;
for(;;)
{
AGetVoicePosition(hVoice[channel],&pos);
if (c[channel] == 0 && pos >= len) break;
if (c[channel] == 1 && (pos < len || pos >= 2*len)) break;
if (c[channel] == 2 && pos < 2*len) break;
osd_update_audio();
}
memcpy(&lpWave[channel]->lpData[len * c[channel]],data,len);
AWriteAudioData(lpWave[channel],len*c[channel],len);
c[channel]++;
if (c[channel] == 3) c[channel] = 0;
}
ASetVoiceVolume(hVoice[channel],volume * 64 / 100);
ASetVoicePanning(hVoice[channel],(pan + 100) * 255 / 200);
}
void osd_play_streamed_sample_16(int channel,signed short *data,int len,int freq,int volume,int pan)
{
playstreamedsample(channel,(signed char *)data,len,freq,volume,pan,16);
}