SAAsound SAA1099 support in Emulator

If you have feature requests, this is the place to post them. Please note your idea may already be something we have already discussed and decided against, or something we are working on privately, and we cannot be held responsible for any similarities in such instance. Whilst we cannot respond to every suggestion, your idea will be read and responded to where possible. Thank you for your input!
m00dawg
Posts: 346
Joined: Wed Jul 08, 2020 12:41 am
Contact:

SAAsound SAA1099 support in Emulator

Post by m00dawg »



1 minute ago, SlithyMatt said:




Not really, it's more memory intensive. Samples take up a huge amount of memory, relatively speaking, compared to PSG or FM settings. But once you have a sample in memory, you don't have to service the PCM FIFO very often, and even then it doesn't take very long. It actually requires less CPU intervention than PSG or FM.



Oh right on! For some reason I thought the CPU had to babysit the FIFO. Actually, that could still be the case if you're wanting to change the PCM data in the buffer right? Looking through the VERA docs, it looks like there's a single buffer space so really only one sample loaded at any time and no way to sort of switch FIFOs? That does mean if one wanted to change the sample that might be somewhat CPU intensive? (Openly asking the question here - I don't know this answer ? ).

I did look a bit at the PSG implementation as well which helps answer some of my other questions. Namely if it has chiptune waveform "buffers" like the GB - it doesn't, although if the DPCM channels can loop then one could do some level of drawable waveforms up to MOD-like capabilities (albeit it with only one sample at a time). Reading the docs that seems like that may be the case given there is a "stop playback" value for the sample rate. So that's pretty cool and does enable some level of GB/FDS/TG16 programmable wave functions here.

Splitting hairs admittedly here, but it'd be great if more of the PSG channels had small wave buffers for chiptune waveforms like noted above. For chips they don't have to be big enough for complex PCM data - just big enough for a single duty cycle (e.g. in LSDJ it's 4-bit samples and uses, if I read the docs right, 16 bytes). Likewise envelope support would be nice (given the 1099 had this), though the implication is that this can be software controlled via the volume register and might not be so bad. I'm not sure how much overhead it would be to have software envelopes on all 16 PSGs though (again open question I don't know the answer to).

Looks like one can change the LR registers too which could be really fun for sound effects. It's a hard pan but even so, things like sword strikes and things could be really fun!

 

 

 

Author of Dreamtracker (https://www.dreamtracker.org/)
Check Out My Band: https://music.victimcache.com/
SlithyMatt
Posts: 913
Joined: Tue Apr 28, 2020 2:45 am

SAAsound SAA1099 support in Emulator

Post by SlithyMatt »



38 minutes ago, m00dawg said:




so really only one sample loaded at any time and no way to sort of switch FIFOs? That does mean if one wanted to change the sample that might be somewhat CPU intensive?



That would be correct. The FIFO loading can be intensive, but only during that burst of loading. You can load balance by doing shorter bursts more often, which would also prevent you from wasting cycles on FIFO'd sample data that is flushed before it plays.

SlithyMatt
Posts: 913
Joined: Tue Apr 28, 2020 2:45 am

SAAsound SAA1099 support in Emulator

Post by SlithyMatt »



42 minutes ago, m00dawg said:




Likewise envelope support would be nice (given the 1099 had this), though the implication is that this can be software controlled via the volume register and might not be so bad. I'm not sure how much overhead it would be to have software envelopes on all 16 PSGs though (again open question I don't know the answer to).



It wouldn't be too bad, as the X16 has so much more RAM and CPU cycles to spare compared to the C64 or the NES, which needed hardware support to do that effectively. Ultimately, you'll still end up ahead, especially if you do the envelope handling programmatically, rather than timed hard-coded changes to the PSG registers, which could take up a lot of RAM compared to an envelope spec.

m00dawg
Posts: 346
Joined: Wed Jul 08, 2020 12:41 am
Contact:

SAAsound SAA1099 support in Emulator

Post by m00dawg »



9 minutes ago, SlithyMatt said:




It wouldn't be too bad, as the X16 has so much more RAM and CPU cycles to spare compared to the C64 or the NES, which needed hardware support to do that effectively. Ultimately, you'll still end up ahead, especially if you do the envelope handling programmatically, rather than timed hard-coded changes to the PSG registers, which could take up a lot of RAM compared to an envelope spec.



Right and of note, if comparing to the NES, software envelopes don't have to be overly precise here.

In looking at the docs, a routine to update the volume of all 16 channels would be something like:

Set $9F20-9F22 to $1F9C2

Set skip to 4 via high bytes of $9F22

For each channel:

  LDA $VOL

  STA $9F23

Forgive the awful pseudo code haha. Basically setting the VERA addresses to point to the PSG registers, setting the skip so we only update the volume on each pass, then doing it 16 times for all channels. That's the most basic case though - each channel may have a different software envelope, so in reality I would guess there's going to be some sort of LUTs that comprise the envelopes that need to be read to know what value to set. I'm kind of assuming how it works in, say, Famitracker here, but for compact code, I wonder if it might use less memory to have compacted tables (and to skip envelopes altogether for instruments that aren't currently using them).

Or hmm for simple things, like the equivalent of a volume slide in a tracker, those are usually linear (in terms of an envelope) and would just be subtracting the current volume by some constant.

Now I'm getting a little excited haha. Of note, since we have stereo we can do some really nice 8-bit chorus stuff in stereo (ala "The MegaMan" chorus but in stereo!)

 

 

 

Author of Dreamtracker (https://www.dreamtracker.org/)
Check Out My Band: https://music.victimcache.com/
User avatar
StephenHorn
Posts: 565
Joined: Tue Apr 28, 2020 12:00 am
Contact:

SAAsound SAA1099 support in Emulator

Post by StephenHorn »



6 minutes ago, m00dawg said:




Now I'm getting a little excited haha. Of note, since we have stereo we can do some really nice 8-bit chorus stuff in stereo (ala "The MegaMan" chorus but in stereo!)



Oh, I'm fully expecting it would be possible to replicate RushJet1's VRC7 covers of Megaman games. The only trick is that certain effects that the NES used to be able to do on its own would have to be done in software on an X16, such as pitch bending/sweeps. I'm not sure how the VERA will treat a subtle pitch change, or if it'll produce audible artifacts.

Developer for Box16, the other X16 emulator. (Box16 on GitHub)
I also accept pull requests for x16emu, the official X16 emulator. (x16-emulator on GitHub)
m00dawg
Posts: 346
Joined: Wed Jul 08, 2020 12:41 am
Contact:

SAAsound SAA1099 support in Emulator

Post by m00dawg »



27 minutes ago, StephenHorn said:




Oh, I'm fully expecting it would be possible to replicate RushJet1's VRC7 covers of Megaman games. The only trick is that certain effects that the NES used to be able to do on its own would have to be done in software on an X16, such as pitch bending/sweeps. I'm not sure how the VERA will treat a subtle pitch change, or if it'll produce audible artifacts.



Ooooh snap I hadn't though about slides either. Or for that matter any other effects like PWM slides, arps, etc. NES had the hardware pitch slide stuff, and while I never quite understood it ? I could make some really fun rowdy noise effects. That might be a bit more intensive on the X16 perhaps?

Author of Dreamtracker (https://www.dreamtracker.org/)
Check Out My Band: https://music.victimcache.com/
User avatar
StephenHorn
Posts: 565
Joined: Tue Apr 28, 2020 12:00 am
Contact:

SAAsound SAA1099 support in Emulator

Post by StephenHorn »



3 hours ago, m00dawg said:




Ooooh snap I hadn't though about slides either. Or for that matter any other effects like PWM slides, arps, etc. NES had the hardware pitch slide stuff, and while I never quite understood it ? I could make some really fun rowdy noise effects. That might be a bit more intensive on the X16 perhaps?



Well, it looks like these effects would have to be driven by software instead of hardware. This would probably cost you somewhere on the order of 40-80 cycles for the first channel, but subsequent channels could have their costs greatly reduced (probably to around 20-ish cycles) with some clever setup. It also depends on how much memory you're willing to throw at the problem. Personally, since I seem to be willing to dedicate all of one entire himem bank to a single significant feature (math and graphics tricks, so far), I could see myself creating up to some 8KB's worth of table data to drive software-based audio effects. Though I probably won't need that much (my math lib only uses 1.5KB so far, and graphics about the same).

To be clear, the SAA1099 has the same "deficiency" relative to the NES' APU. And I seem to recall that giving instructions to it was roughly as cumbersome as working with VRAM addresses in the VERA, and along with the VERA's clever tricks for reducing the costs of sequential accesses, I don't think the VERA represents that substantial of a loss in runtime performance, either.

Developer for Box16, the other X16 emulator. (Box16 on GitHub)
I also accept pull requests for x16emu, the official X16 emulator. (x16-emulator on GitHub)
m00dawg
Posts: 346
Joined: Wed Jul 08, 2020 12:41 am
Contact:

SAAsound SAA1099 support in Emulator

Post by m00dawg »



13 hours ago, StephenHorn said:




... I could see myself creating up to some 8KB's worth of table data to drive software-based audio effects. Though I probably won't need that much (my math lib only uses 1.5KB so far, and graphics about the same).



Yep I thought about this as well, plus simple add/subtract per "game tick" or vblank for some of the linear effects, like an in-pattern volume slide rather than an actual envelope. The Axy effect in Famitracker-speak. If I interpreted the docs correctly, the VERA will handle the logarithmic nature of the volume, so we only have to think of it as linear. So a volume slide down is just subtracting a constant from the set volume.

Envelope tables wouldn't be too bad given the 6-bit volume. Could even add panning automation since you get the L/R for free. So that's 1 byte per step. In Famitracker, my average envelope length is usually say 5-8 steps for most instruments. I sometimes used a few longer sweeping envelopes for pads and strings but tended to do that more via pattern data (using Axy as noted above). Some RAM will be needed for which envelope is being used and at what position - that's 32 bytes for all 16 channels I think. All told using an 8kb page would be plenty I think for envelope tables. Even 1kb might be plenty, leaving room perhaps for other things for that page (like instrument definitions or some such).

Since the waveform and pulse-width are also packed into 1 byte, the same thing could be done for PWM with being able to switch instruments within the envelope as a weird bonus ? In thinking about the L/R and waveforms - a better use of the top bits in these envelopes might be a loop flag or some such, though given the space we have, could also set aside a byte or two with the envelope to track loops and optionally an envelope speed modifier maybe (like if you wanted the envelope to go slower and only update say on every X vblanks).

Given the frequency calculation on the VERA, note tables would be a nice to have too. For standard tuning (A=440Hz), that could be another use case to put in ROM as well. 8 ocatves is 96 notes which would just a 192 byte (given the 16-bit pitch values) table. That way folks can just think "play an A#" instead of figuring out the math to get what frequency that is. If folks want to use non-standard tuning, that can be done by adding/subtracting from the table.

So yeah hmm given me lots of ideas there Stephen!

Author of Dreamtracker (https://www.dreamtracker.org/)
Check Out My Band: https://music.victimcache.com/
m00dawg
Posts: 346
Joined: Wed Jul 08, 2020 12:41 am
Contact:

SAAsound SAA1099 support in Emulator

Post by m00dawg »


Self reply fail, but thought I would share my thoughts in maybe a more succinct way, so created a quick envelope format definition here:

https://gitlab.com/m00dawg/commander-x16-programs/-/blob/master/command_tracker/file_formats/envelopes.md

I think it could be further optimized. For instance, on a playback routine, once we know if we're looping or not, and where, we really just need to index into the envelope positions. The way I defined it, if an envelope isn't looping, the next byte after the header is the first step in the envelope and the code then just needs to follow that for the envelope length. If there's loops, the next 2 bytes define the loop start and end.

This is probably trivial for some or lacking in details for others, but figured I would put my thoughts somewhere.

The other files might be useful but were when the SAA1099 was around and I haven't put any thought into how the VERA PSG would change things (for one there are now more channels).

Author of Dreamtracker (https://www.dreamtracker.org/)
Check Out My Band: https://music.victimcache.com/
m00dawg
Posts: 346
Joined: Wed Jul 08, 2020 12:41 am
Contact:

SAAsound SAA1099 support in Emulator

Post by m00dawg »


Moved my ideas over to another thread since I kinda moved it a bit far off-topic from this one.

Author of Dreamtracker (https://www.dreamtracker.org/)
Check Out My Band: https://music.victimcache.com/
Post Reply