#include "sound.h"
#include <SDL2/SDL.h>
+#include "psg.h"
#include "resource.h"
#include "ym2151.h"
+#define SAMPLE_RATE 48000
+#define BUFFER_SIZE 512
+
// Function prototypes
void SoundFunc(void *, Uint8 *, int);
extern uint8_t voice_rom[]; // PCM data pointer
static bool soundInitialized = false;
-const float sampleBase = 44010.0/6000.0; // Btwn 5512.5 and 6000
-bool snd_go = false;
-bool chan1_go = false, chan2_go = false, chan3_go = false;
-bool chan4_go = false, chan5_go = false, chan6_go = false;
-uint8_t * sndp1, * sndp2, * sndp3, * sndp4, * sndp5, * sndp6;
-uint32_t rom_pos, end_pos;
+const float sampleBase = (float)SAMPLE_RATE / 6000.0; // Voice is between 5512.5 and 6000 Hz
+bool chan1_go = false, chan2_go = false;
+bool chan6_go = false;
+uint8_t * sndp1, * sndp2, * sndp6;
uint32_t spos1, end_pos1;
uint32_t spos2, end_pos2;
-uint32_t spos3, end_pos3;
-uint32_t spos4, end_pos4;
-uint32_t spos5, end_pos5;
uint32_t spos6, end_pos6;
-float sample1;
-uint8_t prevSamp1;
-int8_t delta_x1;
-float sample2;
-uint8_t prevSamp2;
-int8_t delta_x2;
+float sample1, sample2;
+int16_t prevSamp1, prevSamp2;
uint16_t snd_num;
-uint8_t * snd_array[3] = { sunknown, scya, scamera }; // From RESOURCE.H
+// From RESOURCE.H
+uint8_t * snd_array[3] = { sunknown, scya, scamera };
uint32_t snd_lens[3] = { sunknownlen, scyalen, scameralen };
-
void InitSound(void)
{
- // params 1, 4 & 5 are useless
-// if (YMInit(1, 3579580, 22050, 16, 512))//, (SAMPLE **)sbp))
- if (YMInit(1, 3579580, 44100, 16, 512))
+ if (YMInit(3579580, SAMPLE_RATE))
{
printf("SOUND: Could not init YM2151 emulator!\n");
- return;// -1;
+ return;
}
+ InitPSG(SAMPLE_RATE);
+
SDL_AudioSpec desired, obtained;
- desired.freq = 44100;
+ desired.freq = SAMPLE_RATE;
desired.format = AUDIO_S16;
desired.channels = 1;
- desired.samples = 1024;
+ desired.samples = BUFFER_SIZE * 2; // Size is in BYTES, so x2
desired.callback = SoundFunc;
desired.userdata = NULL;
- // Also, should check to see if it got the hardware it needed, correct sample size, etc.
+
+ // Also, should check to see if it got the hardware it needed, correct sample size, etc. (actually, SDL guarantees we get what we asked for--I think)
if (SDL_OpenAudio(&desired, &obtained) < 0)
{
soundInitialized = false;
soundInitialized = true;
}
-
void SpawnSound(int type, int snd, int channel/* = 0*/)
{
- extern uint32_t psg_lens[16];
- extern uint8_t * psg_adrs[16];
- extern uint32_t voc_lens[32];
- extern uint8_t * voc_adrs[32];
- extern uint32_t fm_lens[14];
- extern uint8_t * fm_adrs[14];
-
if (!soundInitialized)
return;
snd_num = snd;
-// SpawnMsg(MSHOWNUMS);
+ // Voice type sounds...
if (type == GAMESOUND)
{
// Will that do it??? Yes!!!
chan2_go = true;
}
}
- else if (type == PSGSOUND)
- {
- if (snd_num & 0x10) // Second channel?
- {
- spos3 = 0;
- end_pos3 = psg_lens[snd_num & 0x0F];
- sndp3 = psg_adrs[snd_num & 0x0F];
- chan3_go = true;
-
- if (spos3 == end_pos3)
- chan3_go = false; // No sound loaded, so don't do it!
- }
- else // First channel
- {
- spos4 = 0;
- end_pos4 = psg_lens[snd_num & 0x0F];
- sndp4 = psg_adrs[snd_num & 0x0F];
- chan4_go = true;
-
- if (spos4 == end_pos4)
- chan4_go = false; // No sound loaded, so don't do it!
- }
- }
-#if 0
- else if (type == FMSOUND)
- {
- spos5 = 0;
- end_pos5 = fm_lens[snd_num];
- sndp5 = fm_adrs[snd_num];
- chan5_go = true;
-
- if (spos5 == end_pos5)
- chan5_go = false; // No sound loaded, so don't do it!
- }
-#endif
else if (type == USERSOUND)
{
spos6 = 0;
}
}
-
-void SoundFunc(void * userdata, Uint8 * buff, int num)
+void SoundFunc(void * userdata, Uint8 * buffer, int num)
{
- static bool psg1go = false, psg2go = false;
- // Length / 2 is because it's set up for 16-bit samples
-// YM2151UpdateOne(buffer, length / 2);
- // Have to go into ym2151.cpp and change this manually back to 8 bit
- YM2151UpdateOne(buff, num / 2);
-// return;
+ // We do num / 2 because num is in BYTES, and the buffer uses signed WORDs.
+ YM2151UpdateOne(buffer, num / 2);
+ UpdatePSG(buffer, num / 2);
// 0-22 different sounds...
- uint16_t cnt = 0, sample;
+ uint16_t cnt = 0;
uint8_t start_samp1, end_samp1, start_samp2, end_samp2;
- uint8_t samp1 = 128, samp2 = 128, samp3 = 128,
- samp4 = 128, samp5 = 128, samp6 = 128; // Zero samples...
+ int16_t samp1 = 0, samp2 = 0, samp6 = 0; // Zero samples...
- // Kill sound...
-// memset(buff, 128, num);
-
- if (!(chan1_go || chan2_go || chan3_go || chan4_go /*|| chan5_go*/ || chan6_go))
+ if (!(chan1_go || chan2_go || chan6_go))
return;
while (cnt != (num / 2))
{
if (sample1 < 1)
{
- samp1 = voice_rom[spos1++];
+ uint8_t voiceSample = voice_rom[spos1++];
+ samp1 = ((int16_t)voiceSample - 128) * 160;
// Kill channel 1 if done...
- if (samp1 == 0xFF)
+ if (voiceSample == 0xFF)
{
chan1_go = false;
- samp1 = 128;
+ samp1 = 0;
}
// RLE compression...
- else if (samp1 == 0x00)
+ else if (voiceSample == 0x00)
{
// # of repeats
sample1 += (float)voice_rom[spos1++] * sampleBase;
{
if (sample2 < 1)
{
- samp2 = voice_rom[spos2++];
+ uint8_t voiceSample = voice_rom[spos2++];
+ samp2 = ((int16_t)voiceSample - 128) * 160;
- if (samp2 == 0xFF)
+ if (voiceSample == 0xFF)
{
chan2_go = false;
samp2 = 128; // Kill channel 2 if done...
}
- else if (samp2 == 0x00) // RLE compression...
+ else if (voiceSample == 0x00) // RLE compression...
{
sample2 += (float)voice_rom[spos2++] * sampleBase; // # of repeats
samp2 = prevSamp2;
sample2 -= 1.0;
}
- if (chan3_go)
- {
- samp3 = (psg1go ? sndp3[spos3++] : sndp3[spos3]);
- psg1go = !psg1go;
-
- if (spos3 == end_pos3)
- {
- chan3_go = false;
- samp3 = 128; // Kill channel 3 if done...
- }
- }
-
- if (chan4_go)
- {
- samp4 = (psg2go ? sndp4[spos4++] : sndp4[spos4]);
- psg2go = !psg2go;
-
- if (spos4 == end_pos4)
- {
- chan4_go = false;
- samp4 = 128; // Kill channel 4 if done...
- }
- }
-#if 0
- if (chan5_go)
- {
- samp5 = sndp5[spos5++];
-
- if (spos5 == end_pos5)
- {
- chan5_go = false;
- samp5 = 128; // Kill channel 5 if done...
- }
- }
-#endif
if (chan6_go)
{
samp6 = sndp6[spos6++];
if (spos6 == end_pos6)
{
chan6_go = false;
- samp6 = 128; // Kill channel 6...
+ samp6 = 0; // Kill channel 6...
}
}
// Mix 'em...
-// sample = samp1 + samp2 + samp3 + samp4 + samp5 + samp6 - 640;
- sample = samp1 + samp2 + samp3 + samp4 + samp6 - (5 * 128);
+ int32_t sample = samp1 + samp2 + samp6;
+ sample += ((int16_t *)buffer)[cnt];
// If it overflowed, clip it
- if (sample & 0xFF00)
-// sample = (sample & 0x8000 ? 0x00 : 0xFF);
- sample = (sample & 0x8000 ? 0x0000 : 0xFFFF);
+ if (sample > 32767)
+ sample = 32767;
+ else if (sample < -32767)
+ sample = -32767;
- ((uint16_t *)buff)[cnt++] += sample << 7;
+ ((int16_t *)buffer)[cnt++] = (int16_t)sample;
}
}
-