VGM playback on the SPC
Moderator: Moderators
Forum rules
- For making cartridges of your Super NES games, see Reproduction.
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:
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.
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
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.
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.
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.
Right.
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.0x24 - Unknown command
-
KungFuFurby
- Posts: 264
- Joined: Wed Jul 09, 2008 8:46 pm
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.
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.
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.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.
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.
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.
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.
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.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.
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.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.
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).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.


