SPCPlay - .SPC Music Player


Overview

You may be asking yourselves, what exactly IS SPCPlay? 
SPCPlay is a music player for SNES saved states, coded 
in 100% 32 bit assembly. It can play music from either
a standard save state generated by ZSNES (.ZS*), or an 
SPC saved state (.SPC).

Many of you have been wondering why the soundtrack 
can't just be ripped out of any SNES ROM. For those
of you that have tried Butcha's SNES sound ripping
utility, SNESSOR, you will notice that you can only
rip sound samples. Here's why.

Stored in an SNES ROM are samples, much like the way 
MOD files store them except they are compressed. These
compressed 16 bit samples can be a violin, a harp, maybe
even a moaning voice.  The SPC700 is a CPU which executes
a sound program code to play these samples, for how long,
what pitch, and so forth and the 65816 is the main CPU of
the snes which is responsible for transferring the
program code to the SPC700.  Now the problem here is that
there is no reserved place in the game rom for the sound
program and detecting where the program code data is
located isn't easy.  Many programs also require a double
transfer such as the 65816 first transfers the code to
the spc700, then after some spc700 execution, it then
transfers some other code or data.  So at the moment, the
best way to capture spc700 code is to capture them right
when the song starts in the actual snes emulation.

History


v0.700  - Added an option to raise the pitch level mainly for non-Creative
          brand sound cards.
        - Implemented 4-point gaussian interpolation.  This is the
          interpolation used by the actual snes!  Many thanks goes to
          Neill Corlett for his work on finding this info!
          Of course, this routine takes up an extra cpu load so emulation
          will slow down a bit if your computer isn't fast enough, but
          you can always disable interpolation through the sound options.
        - Fixed up Pitch Modulation method.  Thanks again, Neill!
        - Pitch modulation was modulating from the wrong channel.  Fixed.
        - Tweaked SuperFX timing.
        - Added support for multiple songs stored in memory.  You can
          load them using wildcards through the comamndline.
        - Added support for playlists (see sample.spl)
        - Added the ability to define timers to the playlists
        - Added a timer display.  You can toggle it on and off using
          the 'T' key since it seems to slow down windows a bit when you
          alt-tab out of the player if that option is active.

v0.650 - Pitch was calculated too high.  Thanks to Kode54 for helping out here!
       - Slightly changed SB16 initialization

v0.600 - Sound Engine based on ZSNES v0.985

v0.500 - Version dedicated to Zophar's Domain's (www.zophar.net) 3rd
         year anniversary!  Congrats to Zophar and all his staff!
       - Added header displays for .SPC v0.30 / ID666 format
       - New Sound Engine, based on ZSNES v0.980 (unreleased)

v0.300 - (UNRELEASED / Released as SpcAmp)
       - Added partial support for .SPC v0.20 format
       - New Sound Engine, based on ZSNES v0.850

v0.250 - Finally was able to re-enable SPC700 idle detection/skipper
         Performance has improved nicely
       - Implemented 8bit stereo
       - Updated sound engine to that of ZSNES v0.635
       - Implemented SPC Extra RAM supported (Needed for games
         like Terranigma).  You will need to re-capture songs
         that were captured using ZSNES below v0.600

v0.200 - Pitch was a bit too high in the first release.  Fixed.
       - Several Volume Fixes
       - Completely Rewrote the ADSR/GAIN volume effects engine.
         Lots of bugs removed!  Many games sound much nicer!
       - Sped up sound echoing
       - Fixed some sound echo bugs
       - Added sound channel disable/enable
       - Added Volume Adjustment
       - Implemented .cfg file support (spcplay.cfg)
         Load spcplay once to create a default .cfg file
       - Added .WAV logging support

v0.100 - First Public Release (04/22/98)

Usage

At the moment, SPCPlay can only run files off the commandline.

It can load :

  .ZST Save State files from ZSNES
  .SPC Files Generated from ZSNES

Command Line Options

To get the most out of SPCPlay, use the following switches at your
discretion:

-8    : Force 8 bit sound output (Defaults to 16 bit)
-r #  : Sets sound sampling rate 
        0 = 8000 hz 1 = 11025 hz 2 = 22050 hz (Default) 3=44100 hz
-v #  : Sets the volume level (0 .. 100, 75 = default)
-w fn : Saves a .wav using the current sound settings with fn as the filename
-z    : Enable stereo sound (Default is mono)

Features

- Full SPC700 emulation (may still have bugs left)
- Sound DSP Emulation
    - ADSR/GAIN Volume Effects (still have a few bugs left)
    - Echo Effects
    - FIR Filter   (Thanks feenix65!)
    - Noise Emulation

FAQ

Q1) How do I get these SNES music files?
A1) You can either use a saved state from ZSNES (you make it
    by loading the game and hitting F2 to save at the music
    you want), or by saving the SPC state (by hitting F1 and
    choosing 'Save SPC State' a few seconds before a song starts).

Q2) Why doesn't music from game xxx sound perfect?
A2) Since the SPC emulator isn't perfect, there will always be games
    with not-so-perfect sound.

Q3) How do i get stereo sound?
A3) Use the command line switch -z

Q4) Can I convert these SPC files to MOD?
A4) Not at the moment.  Also, a conversion isn't planned, however, a
    great Super Nintendo Emulator, SNEmul can capture .MOD files directly from
    emulation.

Q5) How come some tunes that are supposed to pan from speaker to speaker
    don't?
A5) You have to enable stereo sound (-z).

Related Sites


Here are some sites you should visit:

ZSNES Homepage   : http://www.zsnes.com/
ZSNES Mirror     : http://www.zophar.net/zsnes/
SNES9X Homepage  : http://www.snes9x.com/
SNEmul Homepage  : http://www.mygale.org/09/cassiop/
Zophar's Domain  : http://www.zophar.net/

Credits


Zophar   : for writing much of this documentation, and for testing.
feenix65 : for the info on FIR Filter

And, of course, all of the people who helped with ZSNES, for without them,
SPCPlay would not be possible.


.SPC File Format


Offset 00000h        - File Header : SNES-SPC700 Sound File Data v0.30
Offset 00021h        - 26,26,26
Offset 00024h        - Version #(/100)
Offset 00025h        - PC Register value (1 Word)
Offset 00027h        - A Register Value (1 byte)
Offset 00028h        - X Register Value (1 byte)
Offset 00029h        - Y Register Value (1 byte)
Offset 0002Ah        - Status Flags Value (1 byte)
Offset 0002Bh        - Stack Register Value (1 byte)
Offset 0002Ch-0002Fh - Empty area, Keep 0 for now

Extended header information : (Ignore when offset 23h has a value of 27)

Offset 0002Eh-0004Dh - SubTitle/Song Name
Offset 0004Eh-0006Dh - Title of Game
Offset 0006Eh-0007Dh - Name of Dumper
Offset 0007Eh-0009Dh - Comments
Offset 0009Eh-000A4h - Date of SPC Dumped in decimal (DD/MM/YYYY)
Offset 000A9h-000ABh - Time in seconds for the spc to play before fading
Offset 000ACh-000AFh - Fade out time in milliseconds
*** Note: The play time/fade out time values of SPC's are either in
  decimal or ASCII format.  To determine the type: If the value is
  bigger or equal than 48*256, then use the ASCII format, otherwise decimal.
Offset 000B0h-000CFh - Author of Song
Offset 000D0h        - Default Channel Disables (0 = enable, 1 = disable)
Offset 000D1h        - Emulator used to dump .spc file
                       (0 = UNKNOWN, 1 = ZSNES, 2 = SNES9X)
                       (Note : Contact the authors if you're an snes emu
                       author with an .spc capture in order to assign
                       you a number)

Offset 000DCh-000FFh - Reserved For Future Use (Please Keep 0 for now)
Offset 00100h-100FFh - SPCRam
Offset 10100h-1017Fh - DSPRam
Offset 10180h-001BFh - unused
Offset 101C0h-101FFh - SPC Extra RAM (Probably is efficient if it is copied
                       over the last 40h bytes of the SPCRam)

* A key on has to be issued right when a .spc file starts to play
