Midi-player code for showing visual feedback of playing tune.
Andrei Ellman

Hi,

I've written some code that allows you to modify the tempo and the pitch-bend of a midi as it is being played. Also, it shows visual feedback (pitch-bend, volume, panning).

Attached is the sourcecode and a Windows executable. Drag the example MIDI file (or any other MIDI file) onto the executable or type the filename on the command-line. Also, passing in '-w' runs the app in windowed mode. Note that not all MIDI files will currently work properly (eg. MIDIs with multiple tempo-change commands or pitchwheel-seisitivity setting commands).

KEYS:
Left-arrow, Right-arrow: Bend pitch on the channel specified in the INI file
Up-Arrow, Down-arrow: Change the tempo
SHIFT: Increase rate of change of arrow keys
CONTROL: Increase rate of change of arrow keys

There is an INI file that lets you change various parameters like the MIDI-channel to alter the pitch-bend of (using the keys), and the pitch-bend-sensitivity. See the comments in the midiplayertest.ini file.

I've focused mainly on the MIDI modification and feedback code. The MIDI player itself hasn't been very well written (eg. the Logic and Render parts of the code are not separate and it could do with some optimizations). It was just put together as a test-app.

There is an issue that still exists when transposing absolute pitch-bend events using aeTransposeTrackPitchBendRel() (MIDI does not allow you to set a relative pitch-bend position, so we must set the absolute pitch-bend and manually rewrite all absolute pitch-bend events in the MIDI data) while the MIDI is playing. What the player does is to first transpose the pitch-bend data and then set the current pitch-bend. However, if there's a pitch-bend event in the playing MIDI that occurs after aeTransposeTrackPitchBendRel() has transposed that part of the data but before aeSetPitchBend() is called, the actual pitch-bend setting would have changed by double that amount (until the next pitch-bend event in the playing tune when it's restored to where it should be). Calling aeSetPitchBend() before aeTransposeTrackPitchBendRel() means that the problem now occurs if the pitch-bend event in the tune is called before aeTransposeTrackPitchBendRel() changes the data. One way round this is to check in aeTransposeTrackPitchBendRel() if a pitch-bend event has occurred each time a pitch-bend command needs modifying, but even the check-and-modify operation is not atomic so the problem would still exist, and besides, checking the pitch-bend state of the currently playing tune before each modification just slows down aeTransposeTrackPitchBendRel(). Any suggestions?

I just thought I'd share this with you to see if you'd find it useful. It does everything I want it to do so I just thought I'd share it. One thing that could be done with it is to add visual feedback for more controllers (eg. vibrato etc.). Another useful addition would be the ability to display Karaoke Lyrics.

I used Doxygen on the midi-modification code (but not the actual midi-player code). See the file htmldocs/index.html for the documentation.

Further information about MIDI programming can be found at:
http://www.midi.org/about-midi/
http://www.borg.com/~jglatt/
http://www.borg.com/~jglatt/tech/miditech.htm
http://www.borg.com/~jglatt/tech/midispec.htm
http://www.borg.com/~jglatt/tech/midifile.htm
http://www.wotsit.org/list.asp?fc=12 (look for MID and KAR info)

[EDIT: The links at http://www.borg.com/~jglatt/ don't seem to be working but they're still in http://www.archive.org ]

The code is based on code found in http://pixwiki.bafsoft.com/mags/7/articles/midi/midi.html but it has been extensively modified and bugfixed.

Any feedback is appreciated.

Enjoy,

AE.

Oscar Giner

WTF! I get this weird thing when i try to download it:

http://www.allegro.cc/files/attachment/595809

Oo?

Andrei Ellman

WTF?! It's a RAR file.

Try saving it instead of opening it.

Oscar Giner

Ok i downloaded it

I get an error message that just says "Error :(". What allegro dll version does it need? Maybe i don't have installed the correct one.

LennyLen
Quote:

WTF?! It's a RAR file.

While the attachment link says it's a .rar, when I downloaded it, it had an .rpm extension (which explains Oscar's image). Renaming it to .rar worked for me though.

The program seems to work fine for me, but I can't comment much on it, as I don't really have a use for such a tool.

Johan Halmén

For my latest game I did some midi music on a Windows machine, using Logic Fun. It sounded good in my game, but when I ported it to my Mac, the music didn't sound good anymore. Drums were too loud and melody almost fainted away. I don't know why. But I thougt it could be nice to be able to alter channel parameters for the midi music in an ini file. I could just have a set of parameters in the ini file and whenever I would test the game on a computer, I could adjust the parameters instead of creating a new midi file with my midi editor and creting a new data file after that.

Your code compiled fine on my Mac. I got it running, but the key control was a bit nervous. I guess you use key[] instead of readkey(). Anyway, I'm going to have a deeper look at it. Very interesting. Thought of putting there a mouse control for the pitch bend and maybe modulation or vibrato. A square with a magic dot in the middle. You grab the dot with the mouse and drag it in 2D. Releasing it would turn it back to the middle.

Andrei Ellman
Oscar Giner said:

I get an error message that just says "Error :(". What allegro dll version does it need? Maybe i don't have installed the correct one.

It uses Allegro 4.2.2 (note that with the 4.2.x series, you must use the correct DLL). I think the error-message is caused by trying to run the program without passing the MIDI filename on the command-line.

LennyLen said:

While the attachment link says it's a .rar, when I downloaded it, it had an .rpm extension (which explains Oscar's image). Renaming it to .rar worked for me though.

The attatchment type I get when I click the paperclip is audio/x-pn-realaudio-plugin. This might explain Oscar's earlier problem.

@Johan:
You can easily use my code to alter the volume of individual tracks. If you want to alter the volume for instruments within the tracks, use the 'Expression' controller when composing the tune. This acts like a multiplier for the volume, so if the volume is measured from 0..1, the actual volume is the volume controller multiplied by the expression controller. Expression can be used for things like volume-envelopes, and volume is used for the overall track-volume.

Also, bear in mind that it's not just a PC vs Mac thing, but each individual type of soundcard and MIDI driver has it's own setof instruments. Don't forget you can select the MIDI driver in the Allegro INI file, or the app's INI file (my MIDI player app lets you select the MIDI driver), but it should be up to the user to choose which MIDI driver they want.

Quote:

I guess you use key[] instead of readkey().

That's true. Doesn't key[] work so well on the Mac? I'm trying to see if a key is pressed down rather than going through the keyboard-buffer so I'm using key[].

Quote:

Thought of putting there a mouse control for the pitch bend and maybe modulation or vibrato. A square with a magic dot in the middle. You grab the dot with the mouse and drag it in 2D. Releasing it would turn it back to the middle.

This was meant to be just a test-app for my on-the-fly MIDI modification code so I wanted to keep it simple. Adding mouse-controls, I would be tempted to use my own GUI library which doesn't yet have a slider-widget.

AE.

Johan Halmén

The key[] works well, but it's damn fast. It's as fast as the logic loop, while readkey() uses the speed of how the keyboard hardware repeats the key strokes.

Andrei Ellman
Quote:

but it's damn fast

Is it still fast even if you don't hold down SHIFT or CONTROL?

The quick fix is to put a second (or even more) vsync()s after the first one. Another fix is to make sure the logic-part is only called once every two (or less) iterations. The proper fix of course is to separate the logic and render portions of the code and make sure the logic doesn't get called as often as the render.

Of course, you could also run it on a slower computer.

AE.

Johan Halmén
Quote:

Of course, you could also run it on a slower computer.

I just threw away my old faithful macintosh Performa 475, 25 MHz. :'(

Arthur Kalliokoski
Quote:

I just threw away my old faithful macintosh Performa 475, 25 MHz. :'(

What? You didn't give it to some poor kid?

Johan Halmén

I also threw away one working 640*480*8 monitor, one working 1024*768*16 monitor and a huge 21" not working monitor. And a working PowerMac 6500. And a crappy PowerMac G3. I still have some scsi and ide HD:s, 4 - 40 GB.

Thread #596941. Printed from Allegro.cc