Allegro.cc - Online Community

Allegro.cc Forums » Allegro Development » Problem with midi.c, perhaps a bug?

This thread is locked; no one can reply to it. rss feed Print
Problem with midi.c, perhaps a bug?
Janbalik
Member #12,221
August 2010

Hi all,

I'm a new member of this forum and I still don't know all about its rules, so sorry if I'm breaking any of those rules. And sorry for my English!

With this message I would like to confirm that something I have found is not a bug or if so, how can I solve it.

I'm working on a midi program which uses the functions of midi.c. Everything is working but when I change a drum kit by another one, no change is done. In fact, the standard kit is always used, even if I set a different one from the beginnig. When I do the same for other tracks (the program is a kind of sequencer/composer) which are not using drum sounds, the sound changes as expected. I mean, if I'm using the sound 10 in channel 1 and I change the sound from 10 to 23 (for example) the change takes effect inmediately. But if I try to use a drum kit in the channel number 10 (the one for this kind of instruments, as the standard GM says), the drum kit never changes, it is always the standard kit. I have debugged everything and this is the only thing I think could be failing:

static void raw_program_change(int channel, int patch)
{
if (channel != 9) {
/* bank change #1 */
if (patch_table[patch].bank1 >= 0) {
midi_driver->raw_midi(0xB0+channel);
midi_driver->raw_midi(0);
midi_driver->raw_midi(patch_table[patch].bank1);
}
/* bank change #2 */
if (patch_table[patch].bank2 >= 0) {
midi_driver->raw_midi(0xB0+channel);
midi_driver->raw_midi(32);
midi_driver->raw_midi(patch_table[patch].bank2);
}
/* program change */
midi_driver->raw_midi(0xC0+channel);
midi_driver->raw_midi(patch_table[patch].prog);
/* update volume */
midi_driver->raw_midi(0xB0+channel);
midi_driver->raw_midi(7);
midi_driver->raw_midi(global_volume_fix(midi_channel[channel].volume-1));
}
}

As you can see, the first instruction checks the channel and the code is only executed when the channel is not 9. This is the channel used for drums (you are right, if you see the midi standard it says that channel 10 is the one for drums, but in the code, even in the Allegro code, the channels begin with 0, so the midi channel 10 corresponds with the internal code channel 9). By the standard GM specifications, if you don't set any drum kit, the standard one is used and I think that is what is happening here. Thus, my question is, why we are checking the channel? I think a program change (in other words, an instrument change) would should done always, with no dependance of the channel, but that explicit instruction checking the channel 9 must have an explanation. Does anyone know it?

Is there any way to modify this code to delete that instruction? I have tryed to do it and recompile Allegro, but the code executed is the old one and not my modified midi.c. I'm working with Code:Blocks and Mingw32 in Windows 7, Allegro version 4.2.2 but perhaps I have not recompile it in the right way. I have done it using a console window with administrator permisions and the following instructions:

fix.bat mingw32
mingw32-make
mingw32-make DEBUGMODE=1
mingw32-make install
mingw32-make install DEBUGMODE=1

But it seems like the sources from SRC folder (in that folder is the file midi.c) are not used... Any error from my side?

If you want to check what I say, I have attached a small midi file created by my program. If you play it with a player like winamp or windows media player you can see its drums are not the standard ones, in other words, it sounds as it should. But if you play the file using a player based on the function play_midi from midi.c (which is the function that uses the piece of code I have detailed above) you can hear the drums are the standard ones. Here is a simple code of a wav/midi player based on that midi.c function:

http://altair.lcc.uma.es/clases/laboratorio/curso200203/tutoriales/Sonidos.pdf

Thanks in advance. Any comment will be very appreciated.

Best regards,

Jose

Ron Novy
Member #6,982
March 2006
avatar

Wow... I haven't been here in so long I almost couldn't remember my password...

Anyway, you're absolutely right. It's a bug. It's been there forever and that must be why some music has always sounded a bit different in Allegro. There also may be other checks against channel 9 (or MIDI channel 10) so take another look through the code just to be sure...

Also be sure the Allegro library (liballeg.a) is being copied to the correct folder in the MinGW installation. If you installed MinGW yourself then that would be something like 'C:\MinGW\lib'.

If you got MinGW with CodeBlocks then it would be a sub-folder of your CodeBlocks installation like 'C:\Program Files\Code Blocks\MinGW\lib' or something similar to that.

In another case where you have two installations of MinGW you may be installing Allegro to C:\MinGW when CodeBlocks is using the one in it's sub-folder...

...
And if none of the above helps then you should try a clean re-build...

mingw32-make clean
mingw32-make clean DEBUGMODE=1
mingw32-make
mingw32-make DEBUGMODE=1
mingw32-make install
mingw32-make install DEBUGMODE=1

You should see allegro re-build everything including your modified 'MIDI.c'

----
Oh... Bieber! I thought everyone was chanting Beaver... Now it doesn't make any sense at all. :-/

Janbalik
Member #12,221
August 2010

Hi Ron,

I have checked the Allegro library and it is in the correct folder. I have also checked if the code has more places where the channel 9 is considered to do or not to do something and I have found more checks, but they are not related with this problem. In fact, I have change manually the values by debug in the piece of code I said yesterday and... wow! then the Allegro player sounds as it should, so I'm pretty sure the problem is only this function and the check against channel 9.

As you suggested, my last choice was to recompile again. I have done it using the "clear" instruction but then, when I recompile the process crashes and says that the file gdi.c has an error :-/ I have tried many times and in different computers with different OS (windows XP and win7) but the compilation always fails. It seems like the cleaning process has cleaned too many things...

Then I have uninstalled Codeblocks, Mingw and Allegro and reinstalled all again, but replacing the midi.c file with my own midi.c. Then, the compilation works right and everything seems to be ok. I have recompile my program, run and... :'( I don't understand. Although I see my midi.c, if I execute it step by step by debug I see that the code which is being executed is not my midi.c, but the original midi.c. It is very rare to see how the process is executing blank lines where there is no code, but those lines were the old midi.c code. When the channel is 9, the process jumps directly to the end of the function, after executing a blank line which corresponds with the old code line: if (channel != 9) {

I'm getting crazy. Has anyone any idea? I don't know what more can I do.

Thank you very much, and specially thanks to Ron and Elias for trying to help me. I appreciate it a lot.

Thomas Fjellstrom
Member #476
June 2000
avatar

Make sure you don't have an old allegro dll laying about anywhere. You need to be using the new one you just compiled.

--
Thomas Fjellstrom - [website] - [email] - [Allegro Wiki] - [Allegro SVN Snapshots] - [Allegro TODO] - [Web Hosting]
"God Bless Joe Pesci" -- George Carlin
"Goto is the buldozer of coding. Sometimes, the buldozer is just the right tool for the job. Not often, but sometimes." -- LordBob

Ron Novy
Member #6,982
March 2006
avatar

Just to be sure... You used clean and not clear, veryclean or distclean? If you used veryclean then you'll have to reinstall the library because that erases some specially generated files... Just be sure to backup any modified files first.

I can't be too sure of what's going on, but when you run the program it's probably using a version of the Allegro DLL that is somewhere else on your system... Like C:\Windows\System32 maybe?? So even if you re-compile the library it won't matter because it is still using the old DLL elsewhere on your hard drive.

Since you're using a modified version of the library, I think the best bet for you is to static link to the allegro library. Since the official 4.2.2 DLL doesn't have those modifications, this will prevent the use of the wrong DLL if you distribute your app later on...

mingw32-make STATICLINK=1
mingw32-make STATICLINK=1 DEBUGMODE=1
mingw32-make install STATICLINK=1
mingw32-make install STATICLINK=1 DEBUGMODE=1

This will build the liballeg_s.a and liballd_s.a libraries. All you should need to do is change your project to link with those instead and then add the ALLEGRO_STATICLINK to your compiler define section...

That should do it ;)

All the information for static linking should be available in the file "Allegro\Docs\Build\mingw32.txt"

[edit] Arg... Thomas Fjellstrom! ::)

----
Oh... Bieber! I thought everyone was chanting Beaver... Now it doesn't make any sense at all. :-/

Janbalik
Member #12,221
August 2010

Thank you for your answers and your help.

You both were right, there was an old dll. And sorry, it was a mistake when I was typing. I wanted to say "clean", as you suggested, Ron. I followed your instructions as you told me.

Well, I have tried to static link the Allegro library. The issue now is that nothing works. I gess there is something I have to specify to the linker but I don't know what because I have followed all the steps you told me and I have reviewed if there is something else in the allegro documentation, but I have not found what is not right. I have set the two static libraries liballeg_s.a and liballd_s.a in the linker section of the project and I have defined the ALLEGRO_STATICLINK in my code but as it doesn't work I have set also the libraries in the global section of Codeblocks. No success. I get a lot of errors like these:

C:\CodeBlocks\MinGW\allegro\lib\mingw32\liballd_s.a(wsystem.o)||In function `sys_directx_desktop_color_depth':|
C:\CodeBlocks\MinGW\allegro\src\win\wsystem.c|410|undefined reference to `_GetDeviceCaps@8'|
C:\CodeBlocks\MinGW\allegro\lib\mingw32\liballd_s.a(wsystem.o)||In function `sys_directx_get_desktop_resolution':|
C:\CodeBlocks\MinGW\allegro\src\win\wsystem.c|441|undefined reference to `_GetDeviceCaps@8'|
C:\CodeBlocks\MinGW\allegro\src\win\wsystem.c|442|undefined reference to `_GetDeviceCaps@8'|

...

I don't know what more I have to set in the linker section or any other.

In the other hand, the allegro DLL library I was using is a downloaded one. I have not build this and following the steps for installing/compilling the allegro library the DLL file is never created. I have trying to recreate it but I have had no success, so using static or dynamic link I don't get what I need.

I'm about to give up and leave the program working doing changes only to the no drums instruments.

Thomas Fjellstrom
Member #476
June 2000
avatar

If you go static, you need to link to a bunch of extra libraries manually. I don't personally remember the full list for windows. But someone else should, and should follow up with it.

--
Thomas Fjellstrom - [website] - [email] - [Allegro Wiki] - [Allegro SVN Snapshots] - [Allegro TODO] - [Web Hosting]
"God Bless Joe Pesci" -- George Carlin
"Goto is the buldozer of coding. Sometimes, the buldozer is just the right tool for the job. Not often, but sometimes." -- LordBob

Ron Novy
Member #6,982
March 2006
avatar

Ah yes... Sorry, it's been so long I forgot...

If I have it right, here are the other libraries you need to link to.

Just go to 'Project'->'Build Options'

Hit the 'Linker' tab...

And just copy and paste this:

-lalleg_s -lkernel32 -luser32 -lgdi32 -lcomdlg32 -lole32 -ldinput -lddraw -ldxguid -lwinmm -ldsound

to the 'Other linker options' section... This is the same as adding each library in the Libraries section only I think this is just easier. As long as either alleg_s or alld_s are the first in the list it should work. And be sure you don't include any libraries twice by adding them to the Libraries section and the Other options section...

Anyway, that should do it... Even though I said that already ::)

----
Oh... Bieber! I thought everyone was chanting Beaver... Now it doesn't make any sense at all. :-/

Janbalik
Member #12,221
August 2010

You are my idols! Thank you very much. Ron, I have specified those libraries and now it works perfectly!! Any instrument change takes effect, even if I change the drum kit instrument. Now I have total control of the tracks of my autocomposer. That was the last step to complete the first prototype of my application so... I'm very happy! Thanks, thanks, thanks! I would have been not able to do it without your help. I'm very grateful to you. ;D

Ron Novy
Member #6,982
March 2006
avatar

No problem Janbalik... 8-)

Music and audio are some of my main interests so I hope we get to see your application sometime.

Have a great time coding. ;)

----
Oh... Bieber! I thought everyone was chanting Beaver... Now it doesn't make any sense at all. :-/

Go to: