========
  Spc2Midi .130 (c)2002-08-27 PeekinSot
  (unfinished) SPC to MIDI converter
  By Dwayne Robinson, using NASM/WDOSX/Alink
  http://fdwr.tripod.com/snes.htm
  FDwR at hotmail.com

The included GUI version is a PREVIEW
It is only an incomplete PREVIEW
Do not make any final judgements
Most all of the menu options are unfinished
You can supply a filename after the program
or drag&drop files from Explorer onto it for now

  1. Changes
  2. About
  3. Features
  4. Requirements
  5. Parameters
  6. Keys
  7. History
  8. Todo


=================
Changes/Additions
=================
.130
- **Preview** GUI version created.
- Rather than using numbers from the source directory (0-255), emulation and
  simulation use uniquely identified samples, since some games remap them
  while playing. Secret of Evermore and DOOM sound correct (no longer the
  wrong instruments) and Return of the Jedi is finally audible. Also should
  fix the rare case of an SPC state captured while the game code begins to
  play but is still setting up the table.
- Added clear oscilliscope, faded oscilliscope, ocean oscilliscope, volume
  bars, and voice info visualizations. And of course, the old horizontal roll
  sheet is still in there. They are slow because of using the GDI
  SetDIbitsToDevice. Any suggestions?
- Set function keys F5,F6,F8 to play/pause/stop. No F7 for record yet.
- Silly fix. MIDI files exported all notes the same volume because of
  debugging code I forgot to remove :/
- Change the stupid hack for drums. Implement drums and banks in all MIDI
  sound and file outputs.
- Stop now stops emulation too, when before emulation would continue. Pause
  still continues preemulate.
- Put hacks in for both "Sailor Moon RPG" and "Super Puyo Puyo 2" (they were
  stuck in an infinite loop polling the data port) but they are not yet
  applied because I'm unsure what method would best detect when those are
  loaded. Header game name would work, but only if a header was present in the
  SPC and wouldn't work with savestates.
- Typo in last version. Dump buffer should have been "dbrr", not "brrd".

.122 2002-08-29
- Spc2Midi finally converts 'SPCs' to 'MIDIs'. The sad thing being most of the
  MIDI exporting code was already done two years ago, I just never bothered to
  finish it :/ Use the "/midi" parameter. It records to a file with the same
  name as the SPC/ZST/ZMV file, but with a .MID extension.
- After much conversion, Windows console version included.
- Note visualization has been removed for now, in preparation for GUI.
- GM synthesizer output for Windows version (if your soundcard has wavetable
  synthesis or a software driver synthesis).
- Dynamic initialization of sound outputs, so if a sound output is toggled on
  that was not originally specified on the command line, it will initialize
  the hardware even while playing.
- Parameter to dump entire BRR buffer to wave file "/dbrr".
- Solo parameter to start playing with only selected voices "/solo#". Voices
  can be in any order, or even 0.
- Disassembly listing parameter "/asm". Before, disassembly could only be
  viewed by recompiling. The listing is my own hybrid syntax. If you don't
  like it, too bad.
- Fast parameter to play at maximum speed on your PC. Plays the whole Mario
  RPG ending parade in only 4 seconds "/fast".
- Tune parameter to play a constant tone 0-12543hz "/tune#". Default is
  A440hz, and for anyone wondering, middle C = 262 (261.625). Press 't' to
  toggle.
- Pitch slide can be disabled while playing. Press 'p' to toggle.
- Parameters may be either DOS '/' or Unix '-' style, whichever you prefer.


==========
Disclaimer
==========
  I work on this project purely because I enjoy it, not to please anyone; but
  in case anyone may benefit from it... here 'tis. If you like, good; if you
  no like, find something you do. Works fine on mine, but if any serious
  unknown bug DOES appear, please inform me!


=====
About
=====
  Background: My first PC was too slow to play even SPC files, so I thought,
  maybe they could be played in realtime if first converted to MIDI files.
  Then you could also send the commands to other devices that understand MIDI.
  My Roland piano simply does not understand SPC700 DSP commands or Impulse
  Tracker modules. Originally started before SpcTool was ever heard of, I
  worked on it up to a point, but lost interest when AntiRes released his. Now
  I've continued my little project because, while SpcTool is a great program
  (try it if you haven't), Spc2Midi has a few unique features.

  What it is: A lean, fast program to (in case you missed the program's title)
  play SNES game music from SPC capture/savestates and convert DSP commands
  into their equivalent MIDI events. 

  What it is not: It is not an SPC player that intends to exactly duplicate
  the beautiful music of the real SNES. For that, there are plenty of other
  great programs that perform that role quite well: SpcTool (AntiRes), SpcPlay
  (Demo), ZdSpc (Nitro), or OpenSpc (Butcha). Spc2Midi can sound the music in
  a variety of ways, far beyond just wave output (what you hear with other
  players). You can select one, combine a few, or play all of them
  simultaneously (it sounds pretty bad though).

  Versions: There are multiple versions included in the zip. Simply delete the
  ones you don't want. If you have never used DOS (what kind of computer user
  are you!?) and never intend to, delete the DOS versions. If on the opposite
  extreme, you hate Windows, get rid of them. The console versions are
  significantly smaller and use less memory and processor time than the GUI,
  but lack the visual interactivity.

  Program Files (if you dlded the program)
  -------------
  spc2midi.exe    Windows GUI version
  spc2midb.exe    Windows console version
  spc2midc.exe    DOS console version
  spc2midd.exe    DOS GUI version
  spc2midi.txt    you're reading it

  Source Code: I'm releasing it purely so others can learn from it (I enjoy
  reading other's code). There is no GNU Public License to it because it's
  selfishly mine, all 15,000 lines :) Hope you can read it. 'Tis more
  liberally commented than most emulation-related source.

  Source Files (if you dlded source code)
  ------------
  (read top comments of spc2midi.asm for a description of each source file)


========
Features
========
- multiple audio output modes
    wave audio samples (native output)
    MIDI file
    External MIDI port
    MIDI synthesizer
    frequency modulation synthesis
    sine wave synthesis
- fast song seeking
- variable tempo
- fast/complete emulation
- disassembly listing
- sample information listing
- BRR buffer dumping
- accurate timing

Wave Output
-----------
  This is native output you would hear coming from the real SNES - minus all
  the extra effects I'm too lazy to add. So it won't sound as good as other
  player cores (ZSNES,SpcTool,Snes9x,SNEesE), but my little program isn't
  meant to compete with them, just give you an idea of what you should be
  hearing. Spc2Midi only supports mono as stereo is really just for fancy
  panning (and more work for moi). ADSR and GAIN are not yet implemented, so
  certain songs will sound notes rising more quickly than expected or lasting
  longer than they should. Other effects like echo, I don't care about and
  probably won't add.

  The sampling rate is variable from 5000-64000hz, not a limited set of
  standard rates. Not all cards support rates as low as 5khz, and to date,
  I've never encountered one that supported higher than 48000hz, but it is
  available just in case. Use lower rates for really slow computers. The
  default is 32khz, since that is the SPC700's true rate.

  Originally intended for pitch correction, you can hear some funny
  transposition by messing with the mixing rate. The default is 1:1 to the
  sample rate - if the sample rate is 22050hz, so is mixing. Note smaller
  numbers result in higher pitches and larger in lower pitches. It may seem
  backwards, but realize the smaller the wavelength is, the more cycles per
  second there are, and thus the higher the frequency is.

MIDI File
---------
  It can convert (maybe I should say 'attempt' to convert) the SPC700 DSP
  commands into equivalent MIDI events. Unfortunately, there is no easy way
  for the program to know what MIDI note should be sounded at a given pitch
  multiplier, what instrument a sample most sound like, or how loud one sample
  sounds over another. Only the trained human ear can accurately discern
  those. So until you are to able manually set the values, all MIDI exports
  may sound slightly (or very much) off key.

  It only records key on/off, pitch, and volume - no ADSR info, pitch sliding,
  echo, or stereo. Some exports sound worse than those of Spc2Midi; some sound
  worse. You want to change the default patch before exporting '/dp#'. Each
  voice is recorded into its corresponding channel (1=1...8=8), except
  percussive sounds, which go into track 10.

  Note MIDIs will only exported forwards and at true speed.

External MIDI Port
------------------
  You should be able to connect the MIDI out on your sound card to an
  electronic keyboard or external synthesizer and hear the music (albeit off
  key or low volume). It seems so strange to hear SNES songs coming through my
  Roland piano ;)  Each voice is recorded into its corresponding channel
  (1=1...8=8), except percussive sounds, which go into track 10. Note that
  MIDI port output ALWAYS means the hardware port, not whatever you may have
  it set to in the MIDI Mapper.

MIDI Synthesizer
----------------
  If you have a wavetable sound card or other software synthesizer, you can
  send events to it (only for the Windows version). Each voice is recorded
  into its corresponding channel (1=1...8=8), except percussive sounds, which
  go into track 10. Note that MIDI synth output ALWAYS means an internal
  synthesizer, not the external port.

Fm Synthesis
------------
  I'll be the first to admit that FM output does not sound anywhere near as
  beautiful as true wave output, but it is a LOT faster! SpcPlay triple faults
  my old 386 at even only 8khz :(, but Spc2Midi can play Mario RPG, DKC, and
  Chrono Trigger music in realtime.

  The DOS version includes a complete set of 128 GM patches (default patch is
  Orchestral Strings), which should sound consistent across multiple
  computers. Only the DOS version has complete control of the FM synthesizer,
  allowing fine changes in pitch slides and exact carrier/modulator
  programming. The Windows version is at the mercy of the driver, meaning the
  instruments will be as good or bad as your driver.

Sine Wave
---------
  Since at least one sound card out there lacks FM synthesis (believe it or
  not), I decided to add another output format that uses digital audio. It
  generates the same pitches as for FM, but only pure sine waves, no attack or
  decay.

Fast Seeking/Variable Tempo
---------------------------
  Something other players lack is the ability to easily, quickly seek to any
  point in the song. Spc2Midi can instantly jump to the front, back, middle, 1
  second forward/backward, or 1/30 second f/b. It can also play at any speed,
  even backwards.

Emulation Core
--------------
  The SPC700 emulation core is for practical purposes complete. Although some
  rare instructions are unverified because I have never encountered any games
  that use them, that's really no problem, since (like I said) I've never
  encountered any games that use them.

  It should be fast enough to run on ANY computer made in the last decade.
  Without wave sample processing, FM alone, it easily plays more than twice as
  fast as SpcTool and SpcPlay. In some cases, good enough to play songs
  (especially ones produced by SquareSoft) in realtime on my 25MHz PC :)

Disassembly Listing
-------------------
  The disassembly is my own hybrid syntax. If you don't like it, too bad. The
  only other notable thing about it is that it shows procedural nesting with
  indentation. The listing can be redirected to a file with ">", even in the
  Windows console version. Use the /asm parameter to show it.

Sample Information Listing
--------------------------
  This will list various attributes of each sample (length, loop length,
  offset, validity, and checksum). The listing can be redirected to a file
  with ">", even in the Windows console version.  Use the /info parameter to
  show it.

BRR Sample Dump
---------------
  Rather than decompress the 4bit ADPCM samples as it plays (very slow),
  Spc2Midi buffers them. The option '/dbrr' simply dumps that entire buffer to
  the file "BRROUT.WAV".

Accurate Timing
---------------
  Place any player beside a real SNES, and eventually the two will drift
  apart. To make the real world thing and the simulation as close as possible,
  I put the two side beside each other and just let them play, gradually
  adjusting the timing fractions until they were just right. So I can honestly
  say that Spc2Midi times very accurately, at least on my PC ;) Use '[' ']'
  for fine 1/30 second synchronization.


============
Requirements
============

Windows:
  CPU   - 80486+ 4MB
  Sound - any card will do, preferably one with wave table GM synth
  OS    - Win95+  Needs no bloated VB DLLs, MFC junk, or .NET framework. Does
          not touch the registry or litter your hard drive with mysterious
          files behind your back.

DOS:
  CPU   - 80386+ 25mhz 4MB
  Sound - SB2, SB Pro, SB16 (or any other compatible one)
  OS    - DOS 6+  Requires either pure DOS or under Win95/98 (Win2k and XP do
          not handle it well).

Both:
  Music - files to play (spc/zst/zmv)  You can listen to SPC capture (.spc,
          .sp1...), ZSNES savestates (.zst), or ZSNES movies (.zmv, which are
          modified savestates).

Tested on
---------
  386 25Mhz       DOS6.22/Win3.11     SB2.1          FM realtime, wave at 8khz
  486 130Mhz      Win95 (gma's old)   SB Pro         All fine
  AMD K6 133Mhz   Win95 (my old pc)   SB16           All fine
  IBM PII 233Mhz  Win95 (dad's)       SB Pro         All fine
  PII 350Mhz      Win95 (my newer pc) Yamaha DS-XG   All fine
  HP P3 500Mhz    Win98 (grandma's)   Crystal Ware   Wave fine, no FM
  P3 900Mhz       Win98 (uncle's)     SB16           All fine

  Btw, I use my relative's PCs for beta testing a lot ;-)

Windows Sound Card Compatibility
--------------------------------
  Not much of an issue. If other programs have sound, so should Spc2Midi. The
  GM and FM synthesizer options are only available if your card supports them.
  Some cards have no FM whatsoever. Some have no wavetable synthesizer so
  direct MIDI commands to a software synthesizer (most of which stink). All
  cards should support digital audio and the MIDI port.

DOS Sound Card Compatibility
----------------------------
  It has worked on every non Win2k/XP PC I've tried, and should be quite
  compatible with various configurations. It does not work with some of the
  cheap new sound cards that completely abandon any SB backwards
  compatibility, legacy emulation for the sake of DOS programs. It may also be
  that your computer's default installation simply didn't include the DOS
  drivers, even though the manufacturer may have written them.

  Card version: SB2.0, SB Pro, SB16
  DMA Channels: 0-7 (supports low DMA channels for 16bit output)
  IRQ Lines:    0-15 (remaps IRQ 2 to 9)
  Sample Rate:  5000-64000hz (default 32khz)
  Bitrate:      8/16 bit (defaults to 16bit for cards that support it)
  Channels:     Mono (stereo will not be supported)
  FM Port:      228/248/.../388h
  MPU Port:     300/330h

  If your autoexec.bat sets the BLASTER variable incorrectly, Windows does not
  set them right, or Windows does not set them at all, don't be surprised when
  you hear no sound. My own computer misreports the true IRQ 9 as IRQ 2 (for
  silly backwards compatibility reasons), so there is a hack for that
  configuration. The FM synthesis should work fine on any computer, excepting
  rare computers that don't have it.

  Example BLASTER variable:
    BLASTER=A220 I5 D1 H5 P300

    A=Address                       (typically 220h)
    I=Interrupt request line        (0-15)
    D=Direct memory access channel  (0-3)
    H=High DMA                      (5-7)
    P=MPU Port                      (usually 300h/330h)

  If you start your computer under pure DOS or without the Windows GUI (hmm,
  does anyone else in this world ever even do that), some of the plug & play
  devices may not be initialized, including the sound card. However, if you
  set your BIOS to initialize them instead of the OS, you might remedy that
  annoying silence. If there is an option like "Plug&Play aware OS", simply
  set it to "no".


==========
Parameters
==========
  Both console and GUI versions accept the same parameters and will start
  playing an SPC capture by passing it the SPC/ZST/ZMV filename. The DOS
  versions only accept 8.3 filenames. Parameters can be either DOS (/) or Unix
  (-) like.

  spc2midi [-/options] filename.ext

Examples
--------
  spc2midi chrono~1.spc
  spc2midi dkc.zs2 /fm /solo82
  spc2midi -info -dbrr som.sp9
  spc2midi /solo145 top.zmv /asm

Options
-------
  as    - wave audio samples (default)
  fm    - good old cheap FM synthesis
  sine  - sine wave synthesis
  dls   - (someday)
  gm    - General MIDI synthesizer (either wavetable card or driver)
  mpu   - external MIDI port (MPU401)
  midi  - export to MIDI file. It records to a file with the same name as the
          SPC/ZST/ZMV file, but with a .MID extension.
  tune# - play constant tone for tuning 0-12543 (default=440hz). Default is
          A440hz, and for anyone wondering, middle C = 262 (261.625).
  nofm  - disable FM initialization
  noda  - disable wave audio
  nompu - disable GM synth initialization
  solo# - start with selected voices. Voices are 1-8, 0 for none.

  r#    - sample rate 5000-64000  (default=32000) decrease for less CPU usage,
          increase for more fidelity
  m#    - mixing rate 2000-200000 (default=32000) for pitch correction or just
          fun
  dp#   - default patch (MIDI instrument 1-128)
  dd#   - default drum sound (percussive instrument 1-128)
  dv#   - default volume (0+)
  db#   - default bank (0-16383)
  df#   - default frequency/base pitch 0-12543hz (default=440hz)
  8     - force 8bit on 16bit sound cards (default=16)
  16    - force 16bit on cards <= DSP3

  info  - sample table information (console version)
  dbrr  - dump entire BRR buffer to wave file "BRROUT.WAV" (console version)
  asm   - show disassembly trace (console version)
  h ?   - the help info you are reading now


====
Keys
====
  Key functions differ depending on what is highlighted. The GUI display
  window and console window keypresses are very similar.

GUI Global
----------
  F5      Play (resumes from current position)
  +Shift  Restart at beginning (and reset tempo)
  F6      Pause (pauses play and silences sound)
  +Shift  Still (pauses play but sound still active)
  F7      Record
  F8      Stop (stops play and any recording)

GUI Display Window
------------------
Muting:
  1-8     Mute/Enable
  0       Mute all
  9       Enable all
  p       Toggle pitch slide effects

Play Control:
  Space   Pause/Play
  Home    Restart, seek beginning
  End     Seek end of emulation
  ~       Toggle fast forward
  BkSpc   Reverse play
  - +     Change tempo
  <- ->   Seek one second
  +Ctrl   Seek ten seconds
  +Shift  Seek 1/30 second
  Ins     Set loop start marker (clears end marker)
  +Ctrl   Set start leaving end marker same (for tighter loop)
  Del     Set loop end marker (clear end marker second press)

Sound Output:
  a       Toggle audio samples (native sound)
  s       Toggle sine wave synthesis
  d       (someday) toggle DLS
  f       Toggle FM synthesis
  g       Toggle General MIDI synthesizer
  h       Toggle external hardware (MIDI port)
  t       Toggle tuning wave

Other:
  Esc    Quit

GUI Attribute Lists
-------------------
  Up/Down Select attribute
  L/Right Increment/decrement value
  +Ctrl   Inc/dec large
  +Shift  Inc/dec small
  0-9     Type number
  BkSpc   Delete last digit
  Home    Lowest value
  +Ctrl   First attribute
  End     Highest value
  +Ctrl   Last attribute
  Enter   Depends on which attribute is selected
  Space   Depends on which attribute is selected
  PgUp/Dn Scroll list up/down
  A-Z     Select attribute starting with letter
  
Console window
--------------
Muting:
  1-8     Mute/Enable
  0       Mute all
  9       Enable all
  p       Toggle pitch slide effects

Play Control:
  Space   Pause
  Home    Restart
  End     End of emulation
  BkSpc   Reverse play
  - +     Change tempo
  <- ->   Seek one second
  , .     Seek 1/30 second

Sound Output:
  a       Toggle audio samples (native sound)
  s       Toggle sine wave synthesis
  d       (someday) toggle DLS
  f       Toggle FM synthesis
  g       Toggle General MIDI synthesizer
  h       Toggle external hardware (MIDI port)
  t       Toggle tuning wave

Other:
        Change sample
  Esc     Quit


=======
History
=======
1999-11-21 (first release)
- Added little "LEDS" to indicate which channels are active.
- Added slight color decay gradient at the beginning of each note to mark
  where each note actually started when some notes started immediately after
  the one before it ended.
- Redid palette colors to make each channel more easily distinguishable (I was
  always getting channels that were close in color mixed up) and so that color
  gradients would be possible.
- You can change the tempo with the "-" "+" keys.
- And for mere amusement, you can even play it backwards with BackSpace.
- Added song seeking, fast forward/backward one second
- Added voice emulation (in addition to FM)
- Improved valid sample detection
- Fixed various clicking sounds in sample output
- Remedied some silent sounds because they used right channel volume only
- Added MPU output (but disabled for now because of strange pc lockups)
- Increased compatibility with a few different/unusual configurations. Low
  DMA channels can be used for DMA transfers.
- Stops notes at end of song (for songs like the FF6 snowy intro)
- Added pitch slide support to both wave and FM. FM actually sounds more off
  key in most instances than before because the frequency is now variable
  0-6211hz rather than being constrained to whole semitones of the GM scale
  (0-127), but it was necessary for smooth pitch sliding.
- Added Sine wave synthesis.
- Added command line arguments to set audio output, sample rate, sample
  size...
- Fixed GM output
- Started working on Windows version
- Changed default FM patch from Pizzicato String to Orchestral String, because
  looped sounds were decaying too fast to hear pitch slides.
- Sine wave synthesis, as an alternative to FM.
- Command line parameters (read below)


======
Future
======
- Must finish GUI!
- Save settings
- Add ADSR levels


(:Peekin:)  eof || ^Z
