Noise generator implementation in VICE

You need an actual VIC.

Moderator: Moderators

nippur72
de Lagash
Posts: 574
Joined: Thu Sep 07, 2006 8:35 am

Noise generator implementation in VICE

Post by nippur72 »

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)

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
            }
        }
    }    
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.
groepaz
Vic 20 Scientist
Posts: 1187
Joined: Wed Aug 25, 2010 5:30 pm

Re: Noise generator implementation in VICE

Post by groepaz »

i reworked the code a bit, now it does work as far as i can tell:

Code: Select all

/* FIXME: what is the init value? what happens on reset? */
static uint16_t noise_LFSR = 0xffff;

void vic_sound_clock(int cycles)
{
    int i, j, enabled;

    if (cycles <= 0) {
        return;
    }

    for (j = 0; j < 4; j++) {
        int chspeed = "\4\3\2\1"[j];

        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;
                    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))) {
                        uint8_t 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 >> 3) & 1;
                        int bit12 = (noise_LFSR >> 12) & 1;
                        int bit14 = (noise_LFSR >> 14) & 1;
                        int bit15 = (noise_LFSR >> 15) & 1;
                        int gate1 = bit3 ^ bit12;
                        int gate2 = bit14 ^ bit15;
                        int gate3 = (gate1 ^ gate2) ^ 1;
                        int gate4 = (gate3 & enabled) ^ 1;
                        noise_LFSR = (noise_LFSR << 1) | gate4;
                    }
                    snd.ch[j].out = snd.ch[j].shift & 1;
                }
                snd.accum += snd.ch[j].out; /* FIXME: doesn't take DC offset into account */
            }
        }
    }

    snd.accum_cycles += cycles;
}
POKE 36878,15 is required first to make any sound, is that the same on the real thing?
then POKE 36877,254 gives me a very light high frequency noise... but 255 creates a rather harsh growling sound. does that sound legit? :)

PS: still some sort of testcase would be nice, so i can verify its not completely bolloks before checking it in :)
I'm just a Software Guy who has no Idea how the Hardware works. Don't listen to me.
nippur72
de Lagash
Posts: 574
Joined: Thu Sep 07, 2006 8:35 am

Re: Noise generator implementation in VICE

Post by nippur72 »

can you share your build workflow? If it's not too complex I would like to compile it and compare to my FPGA and real VIC. Is linux needed?

The "noise_LFSR" variable doesn't need to be initialized. As found by Lance on the other thread, the register will init by itself after a number of cycles thanks to the "& enabled" in the "int gate4 = (gate3 & enabled) ^ 1;" which puts a "1" in the LFSR even if it is all "0"s. I guess this is a trick they used to spare the load/init circuit.
POKE 36878,15 is required first to make any sound, is that the same on the real thing?
yes, it is (it puts the volume to maximum).
then POKE 36877,254 gives me a very light high frequency noise... but 255 creates a rather harsh growling sound. does that sound legit?
yes, it think it's a quirk in the design of the circuit. They first increment and then check for overflow, so when the value is 127 (bit7 not counted) it gets incremented so it wraps down to 0 and you get a low frequency.
PS: still some sort of testcase would be nice, so i can verify its not completely bolloks before checking it in :)
that's not easy at all. Perhaps sampling and comparing the FFT spectrums? Or more simply compare vs a real vic?
groepaz
Vic 20 Scientist
Posts: 1187
Joined: Wed Aug 25, 2010 5:30 pm

Re: Noise generator implementation in VICE

Post by groepaz »

The "noise_LFSR" variable doesn't need to be initialized.
yes and no :) remember that with VICE we are aiming for an autistic level of accuracy - the first couple bits the LFSR produces will be different depending on the init value :) (it doesnt matter in practise, no). my guess would be its all 1s after a powercycle (because that what seems to happen in most cases with NMOS). if there is no reset circuit for it, then the current code should be accurate :)

the easiest way to build vice right now is to use linux - but you can do it on windows too (osx is a bit broken atm). for windows there are instructions here: https://sourceforge.net/p/vice-emu/code ... -Howto.txt
I'm just a Software Guy who has no Idea how the Hardware works. Don't listen to me.
nippur72
de Lagash
Posts: 574
Joined: Thu Sep 07, 2006 8:35 am

Re: Noise generator implementation in VICE

Post by nippur72 »

yes I guess 0xFFFF is a good initialization value.

As for building it -- I'm too lazy to setup the whole build chain, can you send me the resulting xvic.exe? (my email: nino.porcino@gmail.com)
groepaz
Vic 20 Scientist
Posts: 1187
Joined: Wed Aug 25, 2010 5:30 pm

Re: Noise generator implementation in VICE

Post by groepaz »

i uploaded a testbuild here: http://hitmen.c02.at/temp/GTK3VICE-3.3-win64-r36240.zip (untested, i use linux)
I'm just a Software Guy who has no Idea how the Hardware works. Don't listen to me.
nippur72
de Lagash
Posts: 574
Joined: Thu Sep 07, 2006 8:35 am

Re: Noise generator implementation in VICE

Post by nippur72 »

sorry, the .exe do not work (the only one working is x64dtv.exe). A small empty window opens and then closes. But nothing else happens.
groepaz
Vic 20 Scientist
Posts: 1187
Joined: Wed Aug 25, 2010 5:30 pm

Re: Noise generator implementation in VICE

Post by groepaz »

darn, guess thats why i am not building regular windows binaries =D

i have comitted the change to trunk now, you can probably grab a binary from retroplay in a day or two here: https://mega.nz/#F!HklwlAZS!vDiSevLlzGQUQL6wOmvhUg (the change is in r36241)
I'm just a Software Guy who has no Idea how the Hardware works. Don't listen to me.
User avatar
beamrider
Vic 20 Scientist
Posts: 1452
Joined: Sun Oct 17, 2010 2:28 pm
Location: UK

Re: Noise generator implementation in VICE

Post by beamrider »

Windows 10 has a Linux subsystem now..perhaps this can be used?
groepaz
Vic 20 Scientist
Posts: 1187
Joined: Wed Aug 25, 2010 5:30 pm

Re: Noise generator implementation in VICE

Post by groepaz »

perhaps, feel free to try :)

the above link has updated windows builds now... those should work
I'm just a Software Guy who has no Idea how the Hardware works. Don't listen to me.
nippur72
de Lagash
Posts: 574
Joined: Thu Sep 07, 2006 8:35 am

Re: Noise generator implementation in VICE

Post by nippur72 »

I've tested it right now -- it sounds good to me!

Anyone else want to try it? we need more opinions. Until we find a more rigorous way to test it.
groepaz
Vic 20 Scientist
Posts: 1187
Joined: Wed Aug 25, 2010 5:30 pm

Re: Noise generator implementation in VICE

Post by groepaz »

anyone? :)
I'm just a Software Guy who has no Idea how the Hardware works. Don't listen to me.
nippur72
de Lagash
Posts: 574
Joined: Thu Sep 07, 2006 8:35 am

Re: Noise generator implementation in VICE

Post by nippur72 »

what about if we sample the audio during POKE 36877,X at a reasonable high sample rate (e.g. 44100 x 2) and then convert it back to a square wave? I think we should be able to see the same "print" of the emulated sound.

Two problems to solve:
1) choose "X" so that the resulting sound is in the middle of the bandwidth of the audio filters (LP 16Khz + LP 1.6Khz + HP 160 HZ)

2) compensate any small clock difference between VICE and the real VIC20.

Does VICE lets you capture audio in .WAV ?
groepaz
Vic 20 Scientist
Posts: 1187
Joined: Wed Aug 25, 2010 5:30 pm

Re: Noise generator implementation in VICE

Post by groepaz »

sure, you can capture sound from VICE
I'm just a Software Guy who has no Idea how the Hardware works. Don't listen to me.
tlr
Vic 20 Nerd
Posts: 567
Joined: Mon Oct 04, 2004 10:53 am

Re: Noise generator implementation in VICE

Post by tlr »

The tricky thing about the noise generator in the VIC-I is that it doesn't generate the same noise shape every time. It seems to randomly start generating noise with a different frequency content for a while, then switching back. There were claims that this had to do with the timing of turning of the previous sound/noise but any detailed description failed to surface.
Post Reply