I was going to make a Standard MIDI file player for the SPC. However I just noticed I tend to jump on small-scale projects as soon as an idea germinates in my mind, without caring if anyone else in the world shows any interest for the project, and to almost completely forget about my own project as soon as I release it, and instead I never make any progress on larger scale projects.
This is why I'd just like to know if there is any interested people before starting such a project.
Basically it would be a SPC engine made to play music very easily without any programming knowledge, just with a little hex editing. It would not be optimal to be used in a game or anything like that.
Advantages :
- Would be a very convenient way to quickly have some music play on the SPC, to include in a demo for example (the coplexity of the SPC might be a significant part of why the world of SNES demoes is so void)
- No need for special programs to convert or make the music, just copy/paste
Inconvenients :
- The music data would take a lot of space compared to an optimized format / only small song will be able to be played (especially if you want decent samples)
- The user would have to include his own BRR samples as well, and to manage the memory used for the MIDI and BRR on his self. It can be hard to find or convert BRR samples and manage memory for someone with no programming knowledge
- Would not work with all midis (not too many ticks per beat, only 8 channel polyphony, etc...). In all cases no midi larger than ~50kb could be used, even with the crappiest possible samples.
- Very likely not suited for actual games
I personally don't think there is any need in yet another player that could not be used in games. However, someone may want it.
There is certainly no point to store and parse actual MIDI files in SPC memory, especially considering their sizes - you can run out of space without even having any samples. As you have to put the data into the file with a tool (hex editor), you can easily make a tool that will convert the data and paste it, for user it will be the same.
Also, full GM set certainly won't fit the memory, you have to only put samples that are actually used there.
How about a MML engine with sound effects? It would be possible!
Cute Angela's source contains a MIDI to music for Paul Lay's Sound Driver converter... and for those of you curious, I have seen MIDI used in two ways in actual SNES games. Games composed by Michel Winogradoff stores the MIDI data and samples in there all at once (obviously switching samples and what MIDI file is loaded when needed), while California Games 2 streams and buffers its MIDI data (it is the only one that you can get a few notes out of the SPC if you were to ever try to dump one, yet you can't get the complete music). For both, I can tell because "MThd" can be found in the SPC file, though the MIDIs in Michel Winogradoff's music are RNC'd (they're compressed with Rob Northen's ProPacker).
I was actually considering MML myself as a "SuperMML" SPC sound driver... though I didn't quite get there yet. Here's a post I made on Battle of the Bits for such a sound driver (snipped to only include sound driver information):
Quote:
...maybe one day, I'll make a "SuperMML" SPC sound driver, which handles .mml music and sound effects (and, if it absolutely has to either by user choice or insufficient SPC700 memory, it can support real-time note input, which will result in undumpable SPC files). I might also make it2mml via Python...
Yes, I perfectly agree a MML compiler would be so much better, and I definitely want to do it someday regardless of if I make a MIDI player.
I mean I'd like to do an almost-unniversal multi platform sound engine for the NES, SNES, GBA, DS, and possibly other platforms too, which would be based on MML, which is efficient if compiled efficiently (that is NOT like PPMCK, where repeats are actually coded in repeats, and so on).
It's impossible to convert from MIDI to MML without loosing a lot of informations. For example, pitch bends in MIDI are send in real time, that is if I bent the pitch up I'll have to store multiple pitch bend events at regular intervals. In MML I'd do a single pitch bend macro with the shape I want to bend to. The approach is entierely different, MIDI has been optimized for real-time communication, while MML is optimized for video games (somewhat).
It also goes without saying that MIDI has a polyphonic approach while MML has a monophonic approach.
The MIDI player/parser would be a simple exercise not related to the universal sound engine at all. But after all perhaps it's not worth the trouble.
I should pehaps instead focus on MOD->MML, IT->MML and MID->MML conversion (even if some information is lost) and then MML compiler which is efficient and suitable for video games.
PS : It's intersting to see games actually used MIDI, even though all it's inconvenients. I suspected Tales of Phantasia and Star Ocean used MIDI, as they sometimes uses GM instruments for their patch numbers (i.e. The bass is 34, the trumpet is 56, etc...). However there is no MThd or MTrk, but they could have coded it slightly differently while still being MIDI events, like what the GBA sappy engine did.
An engine supporting real-time note input would be really neat with a project I've had on the shelf for awhile. I found the official schematics for the Super Multi-Tap, and just for kicks I threw together a schematic for 2 Multi-Taps and 8 controllers all built onto a single board. Which is basically useless, since official games only support 5 players through a single Multi-Tap, but the original idea was to make a mock arcade cabinet of N-Warp Daisakusen (which does support dual multitaps), but you know what else you could do with 8 controllers? Ditch the whole idea of 8 controllers, you have 96 buttons... 96 buttons + real-time sound engine... it could be cool.
For Star Ocean and Tales of Phantasia, chances are they used a MIDI to their own custom music format converter. I've only seen a few games actually use raw MIDI files... the rest, if they did use them in the first place, straight out converted them to a custom music format.
Hey, I actually had an idea for an 8-player arcade game... the soundtrack is even extra large, rivaling Earthbound's soundtrack in size (Each music bank that has those in-game SFX use up 32KB maximum of the SPC700 memory for the music alone... there's four for each: a main tune, a continue tune, a "back in action tune" that goes right back to the main tune, and a Game Over tune). I have at least 32 banks dedicated to handling the main level music (thus, totalling 128), and somewhere around half of those are boss battle themes.
WarioWare for GBA uses straight MIDI files with a custom sound font, and I once made a rudimentary extraction tool.
A full nicely sounding GM set could fit in 512K, maybe in 256K even (with ADPCM). So it could be acceptable for GBA where it was common to have 8MB ROMs, but it just wouldn't fit into SNES sound RAM at once, some kind of a instrument/sample manager is a must there.
Such a sample manager could be as easy as scanning the MIDI file for Program Change messages. Or what am I missing?
The OP was talking about inserting a MIDI file into a SPC file with hex editor, that's imply that full GM set is there. And actually no, a sample manager would be more complex than just a simple scanner, as you have to dynamically allocate all needed samples in memory and tell player where they are. For MIDI you would expect to have multilayer instruments, that'll add extra complexity. Not to say it is something very complex, but I think it'll be more complex than a simple custom format music player.
I'm going to completely wing it, but perhaps MIDI is better used for real-time note streaming?
Also, even if you used MIDI for real-time note data streaming, I myself can do calculation on how large a sample can be on average if you wanted to load all of the GM instruments... here's how large the combined number of samples can be (warning: you must subtract some bytes for SPC700 code and variable allocation, so this omits the code): 116,496 = 7281 BRR blocks.
In order to squeeze 128 samples in the SPC700 memory, on average, they would have to be on average 896 samples large... a mere 56 BRR blocks per sample. That's not too good, even for real-time note streaming. This also makes 256 samples at once an even crazier idea when you only have half the sample size for 448 = 28 BRR blocks per samples.
If MIDI is to be used for the SPC700, either you have to load the MIDI files one at a time with their corresponding sample packs, or just stream the MIDI data and switch sample packs when needed (or in an extreme case, load them all at once... but make sure you're not loading 128 samples: only load the instruments you're using... and please don't try to use multiple samples in one instrument).
The Loricel games with Michel Winogradoff's music simply switched samples when the next song was loaded. California Games 2 streamed the MIDI data and if I remember correctly, kept the entire sample pack in one piece, especially when there were a mere three pieces of SFX in the entire game. The only one that is missing that MThd happens to be Rap Jam: Volume One...
Bregalad wrote:
It's impossible to convert from MIDI to MML without loosing a lot of informations. For example, pitch bends in MIDI are send in real time, that is if I bent the pitch up I'll have to store multiple pitch bend events at regular intervals. In MML I'd do a single pitch bend macro with the shape I want to bend to. The approach is entierely different, MIDI has been optimized for real-time communication, while MML is optimized for video games (somewhat) ...
Bregalad wrote:
... I should pehaps instead focus on MOD->MML, IT->MML and MID->MML conversion (even if some information is lost) and then MML compiler which is efficient and suitable for video games.
One thing: Midi is possible for conversion in MML without most loss of data, look at ''3ML'', the MML Creation tool, you can download it at Woolyss or SMW Central.
And SMW hacking actually uses a form of MML called Addmusic, it is formatted to be a solution for this reason, but only for N-SPC and variants...
I never meant 128 GM samples to be loaded in memory at the same time (and in fact drums should be loaded as well - probably totlising in more than 128 "instruments" - although many instruments could be re-used like Piano 1, Piano 2 and Piano 3 being the same). They would end up sounding like simple waveforms anyway since there wouldn't be too many space.
I meant to write a program that just play the SMF file, but the user would have to find instruments, convert them to BRR and insert them in the SPC file (or write code to transmit them to the SPC inside a SMC ROM file) all by himself. This probably kills the "easy to use" argument, unfortunately.
The idea to stream MIDI data though the 4 port bytes is interesting. It would make the SPC act like a "dumb" MIDI synthesizer, and just execute MIDI events that the 65c816 would send to it. Unfortunately, the 65c816 has no custom timer or anything like that, it would probably have to update it's MIDI parsing-and-playing code at a 60Hz, which is very slow.
EDIT : 3ML looks AMAZING ! Unfortunatley I don't have time to play with it right now so I'll have to wait this weekend.
Yeah, the worst part about doing it in real-time is you're at the mercy of the SNES's clock speed, which is 60hz or 50hz, depending on NTSC and PAL settings. However, with IRQs (using the vertical line count as a reference), perhaps you can speed it up at the expense of losing some time to process the game itself.
You know, I'm getting very interested in >Entertainment's Super Spectrum all over again... it's a music maker program for the SNES that was never produced. I saw nothing of it except my own music.
The music I made for that happens to be one of the very few pieces of music that I made for >Entertainment that was eventually successfuly converted over to SPC format (I only made three tracks, figuring the rest would be made by the user).
Speaking of that, making my own music in a tracker in the first place ensures that the only troublesome thing I have to do is determine if the resulting sound is OK to my ears.
KungFuFurby wrote:
Yeah, the worst part about doing it in real-time is you're at the mercy of the SNES's clock speed, which is 60hz or 50hz, depending on NTSC and PAL settings.
Yet NES games had no problem with clocking the music engine at 50 or 60.1 Hz. How many NSFs actually use an update period faster than 16640 µs (NTSC) or 20000 µs (PAL)?
Bregalad wrote:
Unfortunately, the 65c816 has no custom timer or anything like that, it would probably have to update it's MIDI parsing-and-playing code at a 60Hz, which is very slow.
Disclaimer: I don't know anything about SPC/SNES, but even if the parsing code runs at 60 Hz, wouldn't it be possible to buffer the events in SPC RAM so that the SPC code could process them at a higher rate?
SPC700 is a bit slow, but it should be possible. If I remember correctly, I tried 200 Hz update in my music player, and it worked (8 channels). However, there is a problem with clicks when a new sample replaces another sample. To avoid this, you need to do a key off, wait for some time while sound fades out smoothly, then start a new sound. This makes high update rates not so useful.