SPC sound driver algorithm

Discussion of hardware and software development for Super NES and Super Famicom.

Moderator: Moderators

Forum rules
  • For making cartridges of your Super NES games, see Reproduction.
Pires
Posts: 3
Joined: Mon Apr 15, 2013 11:07 pm

SPC sound driver algorithm

Post by Pires »

My first post in here, so first of all, hello everybody in SNESdev (and NESdev) forums, been loving your work here!
Since early this year I have been reading up on SNES development material and did not find any source that addressed this issue in layman terms.

So, can anyone outline an algorithm for an SPC sound driver? How is the music data updated? How are the timers and counters used (never understood how the counters can be of any use if they are reset each time they are read)? And many other issues you feel necessary to be clear.

My goal for now is to make music with SPC files to be read in standalone APU emulators like the plugin for winamp, so I am not concerned in matters of uploading data to the APU RAM, reading screen information, etc. I also don't care for conversion tools of MOD->SPC files as I understand they are somewhat limited and the only limitations I want to work with are the SNES APU's ones.

Thanks in advance for all the attention guys
Shiru
Posts: 1161
Joined: Sat Jan 23, 2010 11:41 pm

Re: SPC sound driver algorithm

Post by Shiru »

There is IPL that offers standart data transfer algorithm. You use it to load any code first, then you can either reuse it load more code/data, or run your own communication code that could work better/faster. IPL is neither good or fast, but it is the only thing for initial upload.

Timers could be needed to update sound state at given rate, say, 240 Hz. You do all update code when wait for timer being non-zero in a loop:

Code: Select all

loop:
 lda {T0OT}
 beq loop
When it is zero, it'll reset to zero, which won't make any difference, when it is non-zero, it'll reset to zero, but your code will move on, and you also will have a value that indicates how many periods the timer is counted (in case your code took too long and ran longer than one period).

SNES APU limitations are actually going far beyond XM/IT/conversion tools limitations.
User avatar
Bregalad
Posts: 8036
Joined: Fri Nov 12, 2004 2:49 pm
Location: Caen, France

Re: SPC sound driver algorithm

Post by Bregalad »

Since the SPC700 CPU doesn't have any interrupts, timers are required for a stable timebase.

Other than this you'd code it like any sound engine, except you only have the sound engine running, and nothing else. Having such a CPU entierely dedicated to sound is probably rather unique to the SNES (although I might be wrong).

A typical sound engine will "tick" multiple channel on a fixed (real time) basis, and then upload the channel's data to the S-DSP regs, and wait for the next tick.
tepples
Posts: 22345
Joined: Sun Sep 19, 2004 11:12 pm
Location: NE Indiana, USA (NTSC)
Contact:

Re: SPC sound driver algorithm

Post by tepples »

Bregalad wrote:Having such a CPU entierely dedicated to sound is probably rather unique to the SNES (although I might be wrong).
Genesis, Neo Geo, Jaguar, Dreamcast, Nintendo DS, Donkey Kong 3 machine...
Shiru
Posts: 1161
Joined: Sat Jan 23, 2010 11:41 pm

Re: SPC sound driver algorithm

Post by Shiru »

Like a thousand of arcade machines also had a dedicated sound CPU/MCU that controlled various sound chips or DSPs, so actually this is very common solution. That is not common is the SPC700 use. Although it seems it wasn't designed specifically for the SNES (but the DSP probably was), I can't recall any other gaming system that had it. Usually it would be something popular, like Z80.

SPC700 is a pretty nice to work with, especially if you ignore the weird official mnemonics and use byuu's replacement, which makes it clear that the MCU is just a well improved 6502 descendant, so a lot of 6502/65816 knowledge easily applied to it.
User avatar
Bregalad
Posts: 8036
Joined: Fri Nov 12, 2004 2:49 pm
Location: Caen, France

Re: SPC sound driver algorithm

Post by Bregalad »

Personally I'd use the "weird" mnemonics (whch are not weird at all, just different).
I think it makes it clearer you're programming the SPC and not a 6502 or anything like this. There is also many extra instructions like INCW or DJNZ which are not in the 6502.
tepples
Posts: 22345
Joined: Sun Sep 19, 2004 11:12 pm
Location: NE Indiana, USA (NTSC)
Contact:

Re: SPC sound driver algorithm

Post by tepples »

Bregalad wrote:I think it makes it clearer you're programming the SPC and not a 6502 or anything like this.
Do you likewise use nocash's 8086 style mnemonics when programming 65816 to make it clearer that it's not a 6502?
Pires
Posts: 3
Joined: Mon Apr 15, 2013 11:07 pm

Re: SPC sound driver algorithm

Post by Pires »

Shiru wrote:There is IPL that offers standart data transfer algorithm.
But so, if I'm compiling an insolated SPC just for pleasure of playing it in an APU emulator then I won't need to be concerned with the IPL, or?
Shiru wrote:You do all update code when wait for timer being non-zero in a loop
Right! So you would have you're own counter in the code to reach the desired number of periods of T2 counter for example. It seems pointless to have a 4 bit counter if you can't wait until it reaches your desired count, right?
Shiru wrote:SNES APU limitations are actually going far beyond XM/IT/conversion tools limitations.
Can you give me an example of this?


Thanks guys for your replys, keep them coming! I'm still expecting a nicely laid out algorithm to work with these so retro but wonderful music making machines. I will eventually come up with my own obviously, but you guys are geniuses and I still have a whole lot to read up on SNES and general assembly programming.
User avatar
Bregalad
Posts: 8036
Joined: Fri Nov 12, 2004 2:49 pm
Location: Caen, France

Re: SPC sound driver algorithm

Post by Bregalad »

But so, if I'm compiling an insolated SPC just for pleasure of playing it in an APU emulator then I won't need to be concerned with the IPL, or?
Correct. You can just disable it and use $200-$ffff as general purpose RAM (normally the IPL ROM sits at the very end of RAM).

One thing you should be particularely careful when using the SPC is that you should always enable a key off one "tick" before a key on, on a particular channel.
If you don't do so, a sudden key on while a note was already playing will "cut" it immediately, causing a noticeable pop in the sound.

This precaution is not required if the key on follows a period of silence where a note was already keyed off, but I just do it this way to be 100% sure all key ons are clean.
User avatar
blargg
Posts: 3717
Joined: Mon Sep 27, 2004 8:33 am
Location: Central Texas, USA
Contact:

Re: SPC sound driver algorithm

Post by blargg »

For an SPC file, you don't need to concern yourself with the IPL loading at all.

Point of counters is in case your code doesn't check often enough, this way it can know how many counts occurred. The hardware is well-designed in this regard. Though true, as you say, mostly it's just read continuously until it becomes 1.

Included is some code I used to make a simple beep, though it's not complete, might still help with getting basic sound.
Attachments
beep_no_macros.asm.txt
(1.36 KiB) Downloaded 110 times
Shiru
Posts: 1161
Joined: Sat Jan 23, 2010 11:41 pm

Re: SPC sound driver algorithm

Post by Shiru »

Pires wrote:Right! So you would have you're own counter in the code to reach the desired number of periods of T2 counter for example. It seems pointless to have a 4 bit counter if you can't wait until it reaches your desired count, right?
You don't have to use the counter. You can set up a required timer period and just go for one period. The counter is only needed if your code potentially could run longer than a period and you would want to compensate it somehow.
Pires wrote:
Shiru wrote:SNES APU limitations are actually going far beyond XM/IT/conversion tools limitations.
Can you give me an example of this?
BRR encoding, samples has to be looped at 16 samples granularity, and only forward looping is possible. It is almost worse than even MOD, and sure far away from XM/IT.
Pires
Posts: 3
Joined: Mon Apr 15, 2013 11:07 pm

Re: SPC sound driver algorithm

Post by Pires »

Shiru wrote:You don't have to use the counter. You can set up a required timer period and just go for one period. The counter is only needed if your code potentially could run longer than a period and you would want to compensate it somehow.
Exactly, thanks, I think I understand now fully how the timers work. So, the development manual must be wrong in saying the maximum value you can write to the timer registers is 01H!?
Shiru wrote:BRR encoding, samples has to be looped at 16 samples granularity, and only forward looping is possible. It is almost worse than even MOD, and sure far away from XM/IT.
Sure, but if you then convert a MOD to an SPC file you are bound to respect the limitations of the SNES APU, right?

Thanks bregalad for the tip and blargg for the test code, will give it a go as soon as I have a proper testing environment set up.
User avatar
Bregalad
Posts: 8036
Joined: Fri Nov 12, 2004 2:49 pm
Location: Caen, France

Re: SPC sound driver algorithm

Post by Bregalad »

BRR encoding, samples has to be looped at 16 samples granularity, and only forward looping is possible. It is almost worse than even MOD, and sure far away from XM/IT.
Resampling can fix the 16 samples granularity problem, and you can simulate pingpong looping by doubling the size of the sample.

That being said a lot of things are possible on SPC which are not possible on MOD (or even XM/IT) like pitch modulation, noise and echo. As far I know I don't think MOD supports automatic volume enveloppe.
tepples
Posts: 22345
Joined: Sun Sep 19, 2004 11:12 pm
Location: NE Indiana, USA (NTSC)
Contact:

Re: SPC sound driver algorithm

Post by tepples »

Double the size of your samples and they won't all fit.
Shiru
Posts: 1161
Joined: Sat Jan 23, 2010 11:41 pm

Re: SPC sound driver algorithm

Post by Shiru »

The whole point of the pingpong looping is to save room.

As for the granularity and resampling, my own experience with this was pretty tiresome, all I can tell is don't expect it'll solve all the problems easily. It is damn difficult to make a seamless loop of anything more complex than a simple waveform on SPC. In general, all the clicky issues on the SPC, such as sample looping and key off, although may seem to have a simple solution, aren't that easily solvable in practice.
Post Reply