Noise generator implementation in VICE
Posted: Wed Apr 24, 2019 4:43 am
This thread forked from 6561 Die Shot Reversing Explorations
@gropaz: this is my first attempt (I haven't tried to compile it yet). Replace the lines ranging from 318-365 with the code below.
Previously the voice j=3 was handled separately, now it's a special case of the more generic sound generation. I leaved the LFSR feedback formula unoptimized for better understanding, I hope I have transcribed it correctly.
I've also have compressed the "if enabled ... else ..." statement into a single case by making an "& enabled";
Note also that sound generation doesn't take into account the DC offset as discussed in this thread (my TODO comment at the bottom)
If you try it, I am curious whether it works or not. You can test it by POKEing 36877, 254, a quickly repeating humming pattern should be heard.
@gropaz: this is my first attempt (I haven't tried to compile it yet). Replace the lines ranging from 318-365 with the code below.
Previously the voice j=3 was handled separately, now it's a special case of the more generic sound generation. I leaved the LFSR feedback formula unoptimized for better understanding, I hope I have transcribed it correctly.
I've also have compressed the "if enabled ... else ..." statement into a single case by making an "& enabled";
Note also that sound generation doesn't take into account the DC offset as discussed in this thread (my TODO comment at the bottom)
Code: Select all
// new noise generator as found by Lance Ewing
unsigned short noise_LFSR; // 16 bit static variable
for (j = 0; j < 4; j++) { // extended to 4 voices
int chspeed = "\4\3\2\1"[j]; // added 4th speed
if (snd.ch[j].ctr > cycles) {
snd.accum += snd.ch[j].out * cycles;
snd.ch[j].ctr -= cycles;
} else {
for (i = cycles; i; i--) {
snd.ch[j].ctr--;
if (snd.ch[j].ctr <= 0) {
int a = (~snd.ch[j].reg) & 127;
a = a ? a : 128;
snd.ch[j].ctr += a << chspeed;
int enabled = (snd.ch[j].reg & 128) >> 7;
// if it's a normal voice or it's noise and LFSR out is 1
if(j !== 3 || (j==3 && (noise_LFSR & 1)) {
unsigned char shift = snd.ch[j].shift;
shift = ((shift << 1) | ((((shift & 128) >> 7)) ^ 1) & enabled));
snd.ch[j].shift = shift;
if(j==3) {
int bit3 = ((noise_LFSR & 1<< 3)>> 3);
int bit12 = ((noise_LFSR & 1<<12)>>12);
int bit14 = ((noise_LFSR & 1<<14)>>14);
int bit15 = ((noise_LFSR & 1<<15)>>15);
int gate1 = bit3 ^ bit12;
int gate2 = bit14 ^ bit15;
int gate3 = ~(gate1 ^ gate2);
int gate4 = ~(gate3 & enabled);
noise_LFSR = (noise_LFSR << 1) | gate4;
}
snd.ch[j].out = snd.ch[j].shift & 1;
}
snd.accum += snd.ch[j].out; // <= TODO doesn't take into accound DC offset
}
}
}