Another MIDI Question + 1st Version of VirtualPiano Attached!
Mr. Big

Now that I know how to find out which note the MIDI player is playing, how do I change the tempo?
I'm planning to add it as a feature to my virtual piano program.
By the way, anyone wants to see the first version? (It's not 3D yet and there are no hands that play the music, but hey, it's a start!)
I'll attach a self-extracting .RAR archive to the post.
(Includes the compiled .exe, the source code and some old recordings of me!)
Watch the program play the third move of the Moonlight Sonata and imagine how fast I had to move my fingers to play it! ;D

Johan Halmén
Quote:

Watch the program play the third move of the Moonlight Sonata

Ahaa, so you wrote it in C#. Well, C# minor.

Mr. Big

L0L! ;D
So, does it work?
Have you spotted any bugs or memory leaks?
There were parts in the program that required the usage of pointers, and me and pointers don't get along too well with eachother.
If it kills your system please don't be angry at me...

Arthur Kalliokoski

I remember slowing down MIDI files by altering one of the bytes in the header with a hex editor. Might have been byte 0xC? Global speed or something. Maybe you can have your program alter how it uses that or alter the value after it's read into memory so you don't have to alter the files.

Evert

May I suggest that you use something other than a self-extracting RAR archive to distribute your source?

Mr. Big

I've included the source code so you could compile and run the program on other platforms and packed it in a .EXE self extractor...
How stupid of me! :-[
I'll attach a .ZIP instead.

[EDIT]

I found this during a Google search:

"To extract the tempo data of a MIDI file, you must find the metaevent which
specifies this. This will look like this in hex:
FF 51 03 xx yy zz

Use filein and then use the match object to find FF 51 03 (247 81 3 in decimal) and
then get the next three bytes. These are concatenated to form a 24bit number, xx is
the MSB and zz the LSB. This represents the number of microseconds per quarter
note. So, if you divide the 24bit number into 60,000,000 the result will be in
bpm.

Bear in mind that this event may be used throughout the MIDI file for dynamic tempo
changes.
The one you want is most likely (but not always) the first."

So I need to modify the next three bytes after FF 51 03.
How do I do that?
Maybe the 'midi_out' function of Allegro could help?
This is Chinese to me... ???
This is not the kind of thing I usually deal with.
Could anyone please help?

Todd Cope

You need to construct the MIDI command data yourself and send it to midi_out().

char mdata[6] = {0xFF, 0x51, 0x03};

mdata[3] = blah;
mdata[4] = blah;
mdata[5] = blah;

midi_out(mdata, 6);

To get the BPM I believe it will be:

60,000,000 / BPM;

I don't know how to construct the 24-bit integer value but I'm sure you could get it with just a couple of tries.

Paladin

You have another problem to look at. Your program doesn't read the key of the midis. I know how to play about half of the moonlight sonata myself and it's playing it incorrectly because it's reading all the notes as naturals. I could be reading an arranged piece, but I'm pretty sure it's correct. :-/

Jeff Bernard
Evert said:

May I suggest that you use something other than a self-extracting RAR archive to distribute your source?

What's wrong with .rar archives? Typically smaller filesize than .zip and you can just download a free program to open them. RARLabs

gnolam

There's nothing wrong with regular RAR archives. Self-extracting archives, however, are works of the devil.

Mr. Big

Todd Cope, thanks, now all I have to do is to figure what to put there instead of "blah-blah-blah". ;D

Brian, everything is fine.
It's just that not every synthesizer has the middle C as key number 60.
Set 'offset' to -4 and it'll show the correct keys.

Paladin

Oh ok I fixed it up, it works now. Heh.

Thread #586224. Printed from Allegro.cc