========
  Spc2Midi .121 (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

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


=================
Changes/Additions
=================
.121 2002-08-27
- 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 "/brrd".
- 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, with or without my adoring
  public (facetiousness intended), but in case anyone may benefit from it...
  here 'tis. If you like, good; if you no like, find something you do. Works
  great on my PC, but no guarantees it will work fine on yours. If any serious
  unknown bug DOES appear, please inform me.


=====
About
=====
  In case you have the program's title, its purpose is to play SNES game music
  from SPC capture/savestates and convert DSP commands into their equivalent
  MIDI events. My was PC too slow to play even SPC files, so I thought, if
  they were converted first to MIDI files, they could be played in realtime.
  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.

  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, not only wave output (what you hear with other players). To select
  which ones to hear, you can pass command line parameters or toggle them with
  keys while playing. You can select one, combine a few, or play all of them
  simultaneously (it sounds pretty bad though).

  There are two versions of the same program, one for DOS and the other for
  Windows. Except for differences in how the two access hardware
  (input/output/audio), they are exactly the same program. Both are console
  programs (no GUI), so if you know not what those even are, perhaps you
  should play with some other program. For now, do not expect anything more
  from my test play player than mere amusement.

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

Files
-----
spc2midi.exe - DOS version
spc2midw.exe - Windows console version
spc2midi.txt - you're reading it
spclog.txt   - more history

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.

  I've given up on the idea of any wave form analysis (automatically
  determining the sample's dominant frequency), and opted for the user (that
  would be you) to instead just manually transpose the sample and set its
  attributes. At least, when the GUI is made ;)

  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.

Wave Output
-----------
  Spc2Midi supports 8bit/16bit output, but only mono - since stereo is really
  just for fancy effects, and more work for moi. As of yet, ADSR and GAIN are
  not implemented (I fully intend to), so certain songs will sound unusal,
  with notes rising more quickly than expected or lasting longer than they
  should. Other effects like echo, I really don't care about and probably
  won't add. The reason why is that this program is written to output MIDI's
  (which generally don't support such fancy effects), not to compete with
  other SPC players.

  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.

  You can also change the mixing rate. The default is 1:1 to the sample rate -
  if the sample rate is 22050hz, so is mixing. Originally intended for pitch
  correction, you can hear some funny transposition by messing with it. 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.

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.

MIDI Synthesizer
----------------
  If you have a wavetable sound card or other software synthesizer, you can
  send events to it. Enable with the /gm parameter - only for the Windows
  version.

  Note that MIDI synth output ALWAYS means the internal synthesizer, not
  whatever you may have it set to in the MIDI Mapper.

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.
  Alternatively, if you set your card to redirect MIDI output to its wave
  table synthesizer (instead of the MPU401), you can hear it that way. MIDI
  output is not enabled by default, so enable with the /mpu parameter. It
  seems so strange to hear SNES songs coming through my Roland piano ;)

  Note that MIDI port output ALWAYS means the hardware port, not whatever you
  may have it set to in the MIDI Mapper.

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#'.

Fast Seeking
------------
  Something other players lack (SpcPlay, ZdSpc, SpcTool, OpenSpc...) is the
  ability to easily seek to a point in the song, short of restarting and
  waiting. Spc2Midi can instantly seek to any point, front, back, middle, 1
  second forward/backward, or 1/30 second f/b. It can also play at any speed,
  and 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. The
  emulation core itself may not be faster than SpcPlay or SpcTool, but it
  certainly isn't any slower. Without wave sample processing, FM alone, it
  easily plays twice as fast. 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 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 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 as needed. The option '/brrd' simply dumps the entire
  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
============
  Processor - 386+ with 2MB
  Sound card - SB2, SB Pro, SB16 (or another compatible one)
  OS - DOS 6+ || Win95+
  Music Files - something to play (spc/zst/zmv)

  The Windows version needs Windows 95 or later (unsure about Win32s) - no
  bloated VB DLLs, .NET framework, or DirectX required. The DOS version needs
  either plain DOS or Win95/98 (Win2k and XP do not handle it well).

  You can listen to SPC capture (.spc, .sp1...), ZSNES savestates (.zst), or
  ZSNES movies (.zmv, which are essentially savestates).

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

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

DOS Sound Card Compatibility
----------------------------
  It has worked on every non Win2k PC I've tried, and should be quite
  compatible with various configurations. I've found it more functional on
  unusual configs than than other DOS SPC players (SpcTool, SpcPlay, OpenSpc),
  but individual mileage may vary. Of course, it sounds nowhere near as good
  ;-)

  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 drivers.

  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
  computers that by some miracle 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. Usually there is an option like "Plug&Play aware OS".
  Simply set it to "no".

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
  redirect MIDI commands to a software synthesizer (most of which stink). All
  cards should support the MIDI port, but whether or not you actually have a
  device connected to the other end makes the difference of hearing nothing or
  something ;)


==========
Parameters
==========
  It has no interal file loader (like SpcPlay and SpcTool), so supply the
  filename after the program. Parameters can be either DOS (/) or Unix (-)
  like.

  spc2midi [-/options] filename.ext

Examples
--------
  spc2midi chrono~1.spc
  spc2midi dkc.zs2 /fm /solo82
  spc2midi -info -brrd 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

  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)
  df#   - default base pitch 0-12543 (default=440hz)
  8     - force 8bit on 16bit sound cards (default=16)
  16    - force 16bit on cards <= DSP3

  info  - sample table information
  brrd  - dump entire BRR buffer to wave file (BRROUT.WAV)
  solo# - start with selected voices. Voices are 1-8, 0 for none.
  asm   - show disassembly trace
  fast  - play at maximum speed on your PC. Plays the whole Mario RPG ending
          parade in only 4 seconds.
  h ?   - the help info you are reading now


====
Keys
====
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 (original 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)
- GM output now works and sounds nicely semi-ok (excepting the lovely off
  keyness). Use /mpu switch. Don't remember what I accidentally changed to
  mess it up. Also don't remember what I did to fix it.


======
Future
======
- Finish GUI!
- Save settings


(:Peekin:)  eof || ^Z
