======== Spc2Midi .130 (c)2002-08-27 PeekinSoŸt (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