Hey everyone,
this is my first GameHero post release. As I already mentioned, I programmed a simple Midi-Player that plays all of the music in my game. I cleaned up the code and removed all of the game logics. Whats left is the basic midi player and some debug output. The zip file includes a binary as well as the complete source code.
The Midi-Player is pretty close to what HorvatM did with his Soviet Union 2011 sound engine, even though our projects are totally unrelated. Actually, our projects are that similar, that I was able to copy most of his introduction text to my project. However, there are major differences in how we handle timing of notes. It basically comes down to this:
– If you want to have sounds in your game you should go with the Soviet Union 2011 sound engine
– If you want to play music in the background you may want to use the GameHero Midi Player
The Midi2VB converter (which is going to be released soon) supports both projects, so the choice is yours.
Even tough both projects look similar, they work together very well. I attached a version of the SU Sound Engine that is able to play sounds as usual but also can use the GameHero MidiPlayer to play music in the background. Therefore, I basically changed nothing in both of our codes. I only used channel 5 for the Midi-Player to avoid interferences.
If someone finds time (not me) it would be a good idea to combine the strength of both systems.
Cheers
thunder
Ohhh… and I am not used to program c so don’t wonder if my code sometimes looks strange (damn pointers).
Attachments:
Hmm… Looks like the NSF to MIDI exporter you’re using doesn’t set different instruments for different channels. Instead, it just dumps the notes into separate channels, and then it sets the channel instrument to square wave and nothing else. The piano ones you’re seeing aren’t specifically set to that – those channels aren’t being set at all, so they default to instrument 1, which is the piano.
However, since it dumps the notes into channels very consistently, this makes things easy regarding instrumentation. It seems to follow the actual NES sound hardware pattern!
From Wikipedia (regarding channels in NES sound hardware):
two square waves, one triangle wave, one noise generator and one digital sample (DPCM) channel
And indeed, channel 1 and 2 are always square waves in your provided MIDIs. Channel 3 is always a triangle wave. You can likely interpret any exported NES MIDI like that.
Since MIDI has no white noise instrument, it sets a drums track for channel 4 and tries to interpret any white noises the NSF makes as drum sounds. It also seems to be failing a lot here – In the third MIDI, only the three longer bits of white noise at the start are interpreted (as an open hi-hat sound) but all the shorter percussion bits that play throughout the rest of the song are missing entirely!
As for the NES’s digital sample channel… No clue if the NSF to MIDI exporter does anything with it at all. Zelda has no samples in its music; that was reserved for the sound effects. Convert some Mario 3 music and see if channel 5 has anything or not.
The music itself is definitely too slow in Mednafen. I wonder if this is a problem with Mednafen or not because this thread states this:
Mednafen has different timing than the Virtual Boy hardware, so its output will not be identical. You can adjust the delay between samples by pressing Up and Down on the left D-Pad.
So you might be right there (unless this only affects his code somehow). There has to be a way to make it consistent, though, considering emulated VB games play music just fine. What’s going on there?
thunderstruck wrote:
It seems to either pick squares or piano as an instrument. I just checked some of the NES specs. I might be wrong but for me it sounds like you can only choose between square and triangle waveforms or use the noise channel.
Looks like you’re right! In that case it’s a triangle wave – they sound incredibly similar so I confused the two.
Checking the VB’s sound hardware specs, to the best of my interpretation it seems that the VB can make all of the aforementioned kinds of sounds, however.
- This reply was modified 11 years, 4 months ago by DaVince.
There’s two routes I think you can go here regarding interpreting MIDI and instrumentation, by the way:
One route:
– Use the pattern the NSF to MIDI exporter uses. By which I mean MIDI channel 1-5 always translates to square, square, triangle, noise, sample in your player.
Upside is that NES MIDIs would always export and sound great. The MIDI instrument isn’t checked at all in this case, just the channel that notes are on, so it’s relatively easy to set up.
Main downside would be that a lot of existing MIDIs wouldn’t work unless they’re simple. (I suppose all classical piano MIDIs would work.) People making music for their game would also make their MIDI according to these rules. Another downside is that you can’t make more kinds of sounds than just the above five (unless you code your player to interpret channels after channel 5 as other sounds).
The other route:
– Interpret the MIDI instruments that MIDI channels use. Is something set up to sound like a piano? Generate a piano-like tone. Is it set up to use the square wave? Use that.
Upside is that a lot of existing MIDIs could be imported without issue straight away (while usually losing a lot of channels due to VB limitations, of course). Also, making the MIDIs themselves is easier and the song composer gets a lot more freedom in how it should sound.
Downsides are that it will take a lot of time and trial and error to generate 128 distinct sounds for the 128 possible MIDI instruments. There’s also the matter of how exactly you’re going to assign the available VB sound channels properly. And you would also have to edit your NSF-exported MIDIs so channel 3 is set up properly (instrument 82, titled “lead 2”, would perhaps be a smart choice).
- This reply was modified 11 years, 4 months ago by DaVince.
DaVince wrote:
There’s two routes I think you can go here regarding interpreting MIDI and instrumentation, by the way:One route:
– Use the pattern the NSF to MIDI exporter uses. By which I mean MIDI channel 1-5 always translates to square, square, triangle, noise, sample in your player.Upside is that NES MIDIs would always export and sound great. The MIDI instrument isn’t checked at all in this case, just the channel that notes are on, so it’s relatively easy to set up.
Main downside would be that a lot of existing MIDIs wouldn’t work unless they’re simple. (I suppose all classical piano MIDIs would work.) People making music for their game would also make their MIDI according to these rules. Another downside is that you can’t make more kinds of sounds than just the above five (unless you code your player to interpret channels after channel 5 as other sounds).
The other route:
– Interpret the MIDI instruments that MIDI channels use. Is something set up to sound like a piano? Generate a piano-like tone. Is it set up to use the square wave? Use that.Upside is that a lot of existing MIDIs could be imported without issue straight away (while usually losing a lot of channels due to VB limitations, of course). Also, making the MIDIs themselves is easier and the song composer gets a lot more freedom in how it should sound.
Downsides are that it will take a lot of time and trial and error to generate 128 distinct sounds for the 128 possible MIDI instruments. There’s also the matter of how exactly you’re going to assign the available VB sound channels properly. And you would also have to edit your NSF-exported MIDIs so channel 3 is set up properly (instrument 82, titled “lead 2”, would perhaps be a smart choice).
Right now I have the second option already implemented in a simple way. Meaning I have waveforms for 6 (I think) different instruments which I can freely assign to each vb channel. The converter checks what is set in the midi and then set the respective waveform. The UI of course allows you to change the waveform to whatever you want as well.
Converting a nsf file to a VB format actually needs one more step. What I do is I convert the nsf to a midi file, then convert the midi file to a differently formated midi file and then convert it to the vb format (nsf->midi->midi->vb). That’s because the nsf converter spits out a midi that is not compatible to my midi library. So I can just change the instruments accordingly while I’m doing the conversion.
The white noise is not implemented right now though. I will have to do something special here as I don’t need to switch the waveform but to use the noise channel in that case.