VGM playback on the SPC

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.
mic_
Posts: 922
Joined: Thu Oct 05, 2006 6:29 am

Post by mic_ »

Ah, yeah, my bad. That value was left over from the first version.
mic_
Posts: 922
Joined: Thu Oct 05, 2006 6:29 am

Post by mic_ »

Btw, does anyone know if the S-DSP volume control is linear or if it follows a logarithmic curve?
User avatar
Bregalad
Posts: 8036
Joined: Fri Nov 12, 2004 2:49 pm
Location: Caen, France

Post by Bregalad »

It's linear.
Useless, lumbering half-wits don't scare us.
mic_
Posts: 922
Joined: Thu Oct 05, 2006 6:29 am

Post by mic_ »

I decided that it'd be a good idea to use as much of the dynamic range of P as possible. So I now calculate my LUT the following way:

Code: Select all

	p = floor(f * 16 / 7.8125)
	if p < #1000 then
		p = floor(f * 64 / 7.8125) + #8000
	elsif p >= #4000 then
		p = #3FFF
	end if
All I need to do then when my player code loads the high byte of a value from the table is to check the negative flag. If set, it picks a sample 4 times as wide and clears bit 15.

The results can be quite noticable, as can be heard in this song from Alex Kidd in Miracle World:

.SPC (old frequency table)
.SPC (new frequency table)
.VGM for reference

With the new table it obviously sounds much more like the original.
User avatar
blargg
Posts: 3717
Joined: Mon Sep 27, 2004 8:33 am
Location: Central Texas, USA
Contact:

Post by blargg »

I found that using a rate of more than around 1.5 results in noticeable aliasing. Surely 3.5 results in lots.
mic_
Posts: 922
Joined: Thu Oct 05, 2006 6:29 am

Post by mic_ »

Actually it's 4.0. Or even 8.0 for really low frequency waves (like "periodic noise" driven by tone2).
But the increased accuracy in the frequency table seems to more than make up for it, since it sounds better now (IMO).
mic_
Posts: 922
Joined: Thu Oct 05, 2006 6:29 am

Post by mic_ »

Here's my little continuation of this project.

Image

Use a real SNES or BSNES to run it, other emulators will likely mess the sound up.
caitsith2
Posts: 74
Joined: Mon May 26, 2008 11:41 pm

Post by caitsith2 »

As usual, Had to rip an SPC and try to figure out what commands drive it.

Command goes on Port 1, and issuing that command, goes onto port 0.

If a command is valid, what is written to port 0, is echoed back, otherwise it is not echoed back. Regardless of whether the value is echoed back, next command to be issued has to have a new value written to port 0.

Valid Commands are

0x21 - Restart Playback of current song
0x22 - Pause / Resume playback
0x23 - Stop Playback, and start standard IPL loader. New song is loaded using standard IPL protocol.
0x24 - Unknown command
0x30-0x3F - Set master Volume
0x40 - Toggle Tone Channel 1
0x41 - Toggle Tone Channel 2
0x43 - Toggle Tone Channel 3
0x44 - Toggle Noise Channel
0x45-0x4F - no known effect, but is treated as valid.

Port 2 and 3 contains the 4 channel visualizers, one channel per nybble. In terms of the driver, Port 2-3 are never written to, only read from, except when using the IPL loader.

When a new song is to be loaded, IPL load song to 0x1700, max size 0xE8C0. When done, IPL jump to 0x0300. Issue command 0x21, new song starts playing.
mic_
Posts: 922
Joined: Thu Oct 05, 2006 6:29 am

Post by mic_ »

Right.
0x24 - Unknown command
When repeat mode is disabled in the GUI I want to know from the playback driver when the song has looped (which it does by modifying the value on port0), so that I can stop it and load the next song. When repeat is enabled I tell the playback driver to not send any such notifications. Command 0x24 toggles a flag in the playback driver which determines if it should send loop notifications or not.
KungFuFurby
Posts: 264
Joined: Wed Jul 09, 2008 8:46 pm

Post by KungFuFurby »

Made a SPC set of all of the included tunes. Trackcount is 32 tunes... that should be the correct number of tracks. Nice work! ^_^

Download collection

Edit: Oops! I missed one track. The file has been updated to reflect this.
Last edited by KungFuFurby on Wed Dec 08, 2010 4:04 pm, edited 2 times in total.
User avatar
Memblers
Site Admin
Posts: 3902
Joined: Mon Sep 20, 2004 6:04 am
Location: Indianapolis
Contact:

Post by Memblers »

That's really cool. I've only tried it on ZSNES so far, though.

I remember a long time ago I had looked at .YM files (from Atari ST) and was curious about playing them on the SPC. But it uses some kind of compression, and bigger than SNES RAM without it, so I didn't try it.
mic_
Posts: 922
Joined: Thu Oct 05, 2006 6:29 am

Post by mic_ »

Memblers wrote: I remember a long time ago I had looked at .YM files (from Atari ST) and was curious about playing them on the SPC. But it uses some kind of compression, and bigger than SNES RAM without it, so I didn't try it.
Yeah, I've thought about YM too. They use LZH IIRC. Perhaps they can be compressed in some other way that's easier to unpack, like I did with the VGM files in my player. And/or you could stream the data from ROM if you don't need to do anything else on the S-CPU.

Another possibility would be SAP (Atari XL/XE music, for the POKEY chip). It's an executable format, but it's a 6502-based system. And the files are usually tiny.
User avatar
Memblers
Site Admin
Posts: 3902
Joined: Mon Sep 20, 2004 6:04 am
Location: Indianapolis
Contact:

Post by Memblers »

I could be remembering wrong, but I think YM format had saved all the registers for each update, instead of doing the time-delta/address/data type thing that I imagine most logged formats would do. In that case, a simple RLE stream for each register would probably work out pretty well.

POKEY with SAP format is a cool idea too. Actually I've been wondering lately how I can make some looped POKEY and 2600 waveforms for my wavetable synth.
mic_
Posts: 922
Joined: Thu Oct 05, 2006 6:29 am

Post by mic_ »

Memblers wrote:I could be remembering wrong, but I think YM format had saved all the registers for each update, instead of doing the time-delta/address/data type thing that I imagine most logged formats would do. In that case, a simple RLE stream for each register would probably work out pretty well.
Sounds reasonable. I haven't looked at any YM files to see how often they typically change the register values. The fact that you've got 10 different envelope shapes and an adjustable envelope speed means that you might have to waste a bit of memory on samples if you want them to sound good. And I don't know how the "special effects" in v6 of the YM format works (e.g. "SID-voice" and "Sync-buzzer") or how common their use is.
POKEY with SAP format is a cool idea too. Actually I've been wondering lately how I can make some looped POKEY and 2600 waveforms for my wavetable synth.
I started writing a music playback engine for the Atari XE/XL earlier this year, but I haven't finished it yet. POKEY has some quirky features, like the ability to combine channels to get higher precision, and the whole distortion control which I haven't looked too closely on.
orwannon
Posts: 40
Joined: Fri Feb 20, 2009 10:07 am

Post by orwannon »

mic_ wrote:Here's my little continuation of this project.

Use a real SNES or BSNES to run it, other emulators will likely mess the sound up.
Works great! Enabling/disabling channels a lot will cause graphical glitches, however. Screenshots made with bsnes (on the real hardware w/ PowerPak, the glitches were worse).

Image

Image
Post Reply