Forums

Sega Master System / Mark III / Game Gear
SG-1000 / SC-3000 / SF-7000 / OMV
Home - Forums - Games - Scans - Maps - Cheats - Credits
Music - Videos - Development - Hacks - Translations - Homebrew

View topic - Ideas & Tricks for Better PSG Sound

Reply to topic
Author Message
  • Joined: 21 Mar 2021
  • Posts: 6
  • Location: Budapest, Hungary
Reply with quote
Ideas & Tricks for Better PSG Sound
Post Posted: Sun Mar 21, 2021 11:31 am
Hi Everyone,

I'm a newcomer to these forums, but I've been lurking for years and reading the reference documents here and there whenever I got some idea in my head. I've been into NES homebrew dev for many years now, and maybe it's time to test some new waters. I'm familiar with Z80 assembly, although I've never sat down before to actually write something complete. I'd be very happy to get a chance and write something audio-related for a homebrew project as well.

One thing I've done on the NES and gave me ideas for the SMS was a PCM-based sound system that runs on an on-board interrupt timer. For the SMS I think something less space-hungry would be enough for a very apparent sound uplift. Thankfully the tools are right there in the machine because we have a 'convenient' scanline interrupt in the VDP to run this off of!

The idea is to improve on the aspect the PSG lacks the most, which is the bass range. So why not try to force these low tones with the CPU manually? It comes at a significant CPU time cost, so there could be two approaches here. In both cases, we need to set one of the square channels to the highest frequency. I would suggest doing this on channel 3 so that we get the extra benefit of being able to produce the highest possible white noise at the same time for better hi-hat sounds on the noise channel. So there are two approaches here:

1st method: At every scanline, the interrupt code changes the attenuation level to $F or a 'volume' variable. The decision is taken based on what bit X is in the 'waveform' variable. The 'waveform' variable specifies 8 on/off steps for the waveform, so you can produce waveforms like these:
- 1111 0000 - square wave
- 1110 0000 - 37.5% pulse wave
- 1100 0000 - 25% pulse wave
- 1000 0000 - 12.5% pulse wave
- 1011 0000 - distorted POKEY-like waves
- 1101 1100

The bit to check in the 'waveform' variable is advanced by one when the 'phase accumulator' variable overflows. At every interrupt a 'latch' value is added to the 'phase accumulator', which allows us to control the frequency and also hit notes that fall in-between an integer division of the sample rate that arises from the interrupts at every scanline. A music engine can control the tone by writing to the 'waveform', 'latch' and 'volume' variables.

One problematic aspect is that this needs to be continued during vertical blank, when the scanline interrupt can not be used. So a carefully planned VDP update routine needs to be in place that updates VDP registers and memory while keeping track of time to call the tone generation code at the right intervals.

2nd method: To lower the amount of CPU time used, the interrupt only occurs every 2 scanlines. There is no 'waveform' variable, and the output toggles between $F and 'volume' when the 'phase accumulator' overflows. So only a low square wave can be produced, but the overall processing is simplified and takes much less CPU time.

These are both severely limiting from a game perspective but I really hope there could be applications of this trick to improve on the base PSG audio. What do you think? Is it feasible in some way, or have I not thought of something?
  View user's profile Send private message Visit poster's website
  • Joined: 30 Jul 2019
  • Posts: 10
  • Location: USA
Reply with quote
Post Posted: Sun Mar 21, 2021 11:53 am
Im very intrigued by this. Typically SMS chiptuners use peridoic noise for better bass but the waveforms youve mentioned I never knew were possible. Could you produce some examples, and do you know if it would be possible in a tracker interface (such as deflemask or sneventracker)?
  View user's profile Send private message Visit poster's website
  • Site Admin
  • Joined: 19 Oct 1999
  • Posts: 13650
  • Location: London
Reply with quote
Post Posted: Sun Mar 21, 2021 1:06 pm
Using the horizontal interrupt also allows some sample playback if you accept even more CPU cost. The impact on the vblank routine is quite difficult to manage, though. For a pure music player you can ignore that though, and just spin wait on the line counter.
  View user's profile Send private message Visit poster's website
  • Joined: 30 Jun 2016
  • Posts: 152
  • Location: Melbourne, Australia
Reply with quote
Post Posted: Sun Mar 21, 2021 1:40 pm
If you don't mind the game not working on 44-pin Mark III/Master System cart slots, you could always stickybeek at the option of a BUSREQ-based cartridge mapper, with the cartridge just manually bashing the volume registers for the Z80.
  View user's profile Send private message Visit poster's website
  • Joined: 21 Mar 2021
  • Posts: 6
  • Location: Budapest, Hungary
Reply with quote
Post Posted: Sun Mar 21, 2021 3:22 pm
POLARIA POYON wrote
Im very intrigued by this. Typically SMS chiptuners use peridoic noise for better bass but the waveforms youve mentioned I never knew were possible. Could you produce some examples, and do you know if it would be possible in a tracker interface (such as deflemask or sneventracker)?


I suppose I could creat some faux examples by setting the refresh rate very high in a tracker to be able to apply the volume changes as fast as a sound routine like I explained could. But an already existing tracker that does similar things is Snoozetracker. It allows different waveforms as well, but something like that would surely require full attention from the CPU to pull off in SMS software.
  View user's profile Send private message Visit poster's website
  • Joined: 05 Dec 2019
  • Posts: 32
Reply with quote
Post Posted: Sun Mar 21, 2021 4:58 pm
I guess you could prototype it in FamiTracker with Namco 163 waveforms.
  View user's profile Send private message
  • Joined: 21 Mar 2021
  • Posts: 6
  • Location: Budapest, Hungary
Reply with quote
Post Posted: Sun Mar 21, 2021 6:51 pm
PinoBatch wrote
I guess you could prototype it in FamiTracker with Namco 163 waveforms.


Yes that's a pretty good idea, combined with the Sunsoft 5B which is much closer to the SN76489 sound than any other NES-related sound source.
  View user's profile Send private message Visit poster's website
  • Joined: 21 Mar 2021
  • Posts: 6
  • Location: Budapest, Hungary
Reply with quote
Post Posted: Mon Mar 22, 2021 5:35 pm
I've cooked up a short demo with the aforementioned simulation setup. It can sound surprisingly similar to a POKEY sound chip honestly!



The added benefit is that you can go as low as you need to, there is no penalty really.
  View user's profile Send private message Visit poster's website
  • Joined: 29 Mar 2012
  • Posts: 673
  • Location: Spain
Reply with quote
Post Posted: Tue Mar 23, 2021 7:17 am
It sounds totally amazing!
  View user's profile Send private message
  • Joined: 05 Sep 2013
  • Posts: 2908
Reply with quote
Post Posted: Tue Mar 23, 2021 11:27 am
so how did you do that? Did you set third channel frequency to the maximum value and then modulate the volume at lower frequency? I wouldn't expect that outcome I'm seeing in the video...
  View user's profile Send private message Visit poster's website
  • Site Admin
  • Joined: 19 Oct 1999
  • Posts: 13650
  • Location: London
Reply with quote
Post Posted: Tue Mar 23, 2021 12:36 pm
The video is a simulation by programming a different sound chip that also does square waves in a kind of compatible way - it’s not yet a real demo.
  View user's profile Send private message Visit poster's website
  • Joined: 05 Sep 2013
  • Posts: 2908
Reply with quote
Post Posted: Tue Mar 23, 2021 1:28 pm
yeah I know, what I meant to say is that if you generate a square wave at the highest frequency possible and then you modulate its volume at 15 KHz rate, I'm not sure you could get a different waveform, rather a sort of oscillation of a really fast square...

you might generate a different waveform at 15 KHz constant rate if you keep the square wave output high, but it's hardly useful
  View user's profile Send private message Visit poster's website
  • Site Admin
  • Joined: 19 Oct 1999
  • Posts: 13650
  • Location: London
Reply with quote
Post Posted: Tue Mar 23, 2021 3:17 pm
It’s equivalent to playing a sample at 15kHz on a single channel - except with a very short repeating chunk of data for the sample. I’m not sure how you achieve variable frequencies and I suspect it will alias badly...
  View user's profile Send private message Visit poster's website
  • Joined: 21 Mar 2021
  • Posts: 6
  • Location: Budapest, Hungary
Reply with quote
Post Posted: Tue Mar 23, 2021 8:28 pm
Maxim wrote
It’s equivalent to playing a sample at 15kHz on a single channel - except with a very short repeating chunk of data for the sample. I’m not sure how you achieve variable frequencies and I suspect it will alias badly...


Yes, that was the idea, the phase accumulator method can let you hit any musical note you want but when the divisor for the sample rate is not a whole number it will result in aliasing. I'm guessing this would be most problematic with higher notes, which are kind of not in the scope of this anyway because the PSG can do that just fine on its own. But a more limiting version could be ditching the phase accumulator altogether, and using a divider instead, so that there's never any aliasing. This would limit the possible frequency range, but starting from a 262 lines × 60 frames = 15,720Hz rate, we can decently hit quite a few bass notes.

https://docs.google.com/spreadsheets/d/1B3wTnIeP8DCt56NDhqigB5hyO_sKFrlumdmliTpD...

If we restrict the wave cycle to only 4 steps the range is expanded, but then the waveforms will be restricted to either a 50% or 25% pulse, which is still better than the base PSG can provide. This method can also significantly lower the CPU usage, because the timing can be adjusted by waiting the desired number of scanlines. This means the lower your note is, the less CPU time will go to processing the sound.
  View user's profile Send private message Visit poster's website
Reply to topic



Back to the top of this page

Back to SMS Power!