vspcplay (visual SPC player)

What is vspcplay

vspcplay is a .spc player based on the snes9x snes apu emulation code, featuring a colored visual (hence the name) memory representation, ability to view memory content simply by moving the mouse around, volume/gain bars, pitch dots and simple port manipulation.

Main UI:
vspcplay uses libSDL for it's display output. Most of the screen space is occupied by the memory surface (512x512). There is a small menubar near the lower edge of the screen. See below for details about each component.

Memory surface:
The main component is the memory surface. The upper left corner is address $0000 and the lower right corner is address $ffff. Reads are colored as blue, writes as green (read+write gives cyan). PC (program counter) execution address are colored as red. Pixels slowly fades, but never completely thus leaving a footprint.

By moving the mouse over the memory surface, you can see a 128 bytes hexdump starting at the address under the mouse pointer. You can toggle the hexdump address lock by clicking in the memory surface. Colors used are the same as in the memory surface, but they are brighter for visibility.

Pitch dots:
The pitch dots represent the pitch of the sample for each track. Pitch increase as the dots moves towards the left.

Volume bars:
Each channel can have it's own left and right volume, which permits panning effects. There is also a gain, which is sometimes used for enveloppe effects. Volume increase as the bars lengths increases.

New in version 1.4: Channels can be muted using the 1-8 keys. 0 toggles mute all / mute none.

Port tool:
The port tool allows you to change the values as if you were the Snes. With some games, you can use this to play sound effects. In some other games, you can even change the tune.

You can use the mouse to click on the + and - to increase or decrease the port value, or you can roll the mousewheel. The changes you make will be visible at addresses $f4 to $f7 (left to right) in the APU memory space.

Game port usage

Below is a table about how to use extra spc features with some games. (Play sound effects, change the tune, etc). This is work in progress. Contributions would be welcomed.
Legend of Zelda 3loz3-*.spc Tune selection: Value in port $f4 selects the tune.
Sound effects: Values in ports $f6 and $f7 plays sound effects.
The value in port $f5 controls how the rain sounds. When set to $ff the rain stops.
Pilotwingsptws-*.spc Tune selection: Value in port $f4 selects the tune. Do it with a menu or information screen tune, otherwise a motor sound kicks in.
Sound effects: Port $f5 and $f7 plays sound effects and beeps.
Port $f6 controls the pitch of the plane motor.
Super Mario Worldsmw-*.spc Tune selection: Values ranging from $0 to $1D in port $f6 selects the tune being played. A value of $ff fades out the current tune.
Sound effects: Values in port $f4 and $f6 plays sound effects.
A Value of 1 in port $f5 plays the jump sound.
Hurry up: If you put a value of $ff in port $f4, the hurry up sound will be played and the music will go faster.
Sim Citysc-*.spc Tune selection: Values from $01 to $13 in port $f4 select the tune.
Sound effects: Values in port $f6 select sound effects due to user actions (place road segment, place zone, etc)
Values in port $f7 is used to control additional sound effects such as airplane noise, disaster noise, etc.
Other:If you change the value in port $f5, the music stops but sound effects will stay active.
Donkey Kong Country 1dkc-*.spc Id of sound effect selected by port $f5. Each time $f4 changes (eg incremented), the sound effect is played.
For sound effects, the most significant bit of $f5 is apparently not used. (eg sound $81 is the same as $01).
Values between $77 and $7F in port $f5 seem to be used for other purposes (changing tune, etc.). When $fd or $fc is in $f5, each time $f4 changes, then playback speed is momentarily increased.

Here is a list of the sound effects IDs. Those which I am not sure are between parentheses.
Donkey Kong Country 2 (Diddy's Kong Quest)dkq-*.spc Sound effects: Values ranging from $00 to $76 in port $f5 select the sound effect to be played when $f4 changes.
Donkey Kong Country 3 (Dixie Kong's Double Troubledkdt-*.spc Sound effects: Values ranging from $00 to around $60 in port $f5 selects the sound effect to be played when $f4 changes.
Super mario kartsmk-*.spc Sound effects: Some values in port $f5 plays some in-game sound effects.
Value ranging from $0 to $7f in port $f6 controls the player's kart motor pitch (value of 0 == off).
The value in port $f7 controls the motor sound volume and panning of karts passing by.
Other: Changing value in port $f4 from $00 to $ff plays a pause sound and reduce the music volume. When changed back from $ff to $00, the music resumes at it's initial volume.

Why I wrote vspcplay

In december 2004, I followed caitsith2's schematics (see his webpage for details) to connect an snes APU (Audio Processing Unit) to a PC using the parallel port. The goal was to play .spc files (Snes music files) on a sound module taken from an SNES console.

I made a page about this project here: Snes APU on a PC).

SPC files are a full snapshot (save state) of the APU's CPU, the spc700. This works fine, but before music starts the full 64kB of memory must be uploaded to the APU, and this takes about 5 seconds...

It occured to me that perhaps only a fraction of memory is used to play a given tune. For instance, there are likely sound effects or maybe also unused instruments. For instance, a tune that only uses 50% of the APU memory could be loaded 50% less time!

So the question was, how to know which memory areas are not used... The .spc file format does not help us, since .Spc's are nothing more than dumps of cpu registers and memory. (see spc_file_format.txt for specification). The only way I thought of is to play the tune in a modified emulator which would log all memory access.

I took the source code of an xmms spc plugin based on Snes9X and converted it in a simple tool to log memory accesses. I knew that snes9x may not be the best APU emulator, but it was the only one not written in assembly and I needed this tool to run on the Sparc workstation I used at the time. I decided to represent the memory as 256 blocks of 256 Bytes. Whenever a reads occurs in particular block, it gets marked as used.

While writing my memory access logging tool, I decided to try to representing the 64KB memory as a 256x256 pixels surface, with a color code for read, write and execution. This looked very cool, I could see the music tracks being read, the samples being used, etc. So I got carried away and added visual volume bars for each channel, moving dots for each channel pitch, a tool to play with port values (The APU and the Snes communicates together using 4 ports).


Version 1.4
July 22, 2022 (Friday)
  • Add an option to output a Wave file (--waveout)
  • Add options to mute/unmute specific channels (--mute and --unmute command-line options)
  • Add keyboard controls (1-8 to toggle mute, 0 to toggle mute all/none, N/P to play next/previous song, R to restart song, ESC to quit)
  • Fix a bunch of buffer overflows, fix warnings, some code cleanup...
vspcplay-1.4.tar.gz (79.1 KB)
Show previous releases...
Version 1.3
November 2, 2005 (Wednesday)
  • Added the --apply_mask_block command line option which applies the mask to the file (fills unused 256 bytes blocks) with a pattern.
  • Added the --filler command line option which is used to specify the filler byte for the --apply_mask_block option. Default is $00
Also, a tool to apply mask files to spc files has been added to the utils/ subdir.
vspcplay-1.3.tar.gz (54.5 KB)
Version 1.2
July 8, 2005 (Friday)
  • Added --status_line command line option (displays a status line in the terminal).
  • Reads in the sample directory were not reported (Resulting in unusable masks)
vspcplay-1.2.tar.gz (65.2 KB)
Version 1.1
June 18, 2005 (Saturday)
  • Added --extra_time (Play x seconds longer than tag time) and --nice (try to reduce CPU used by graphics) command line options and win32 support (with a GUI frontend!!).
vspcplay-1.1.tar.gz (72.2 KB)
vspcplay_win32.rar (710 KB)
Version 1.0
June 9, 2005 (Thursday)
Initial release
vspcplay-1.0.tar.gz (50.5 KB)
This project is also available on GitHub!
To request features, report issues or contribute, you may send me an email or use the GitHub repository: