Allegro.cc - Online Community

Allegro.cc Forums » Programming Questions » Midi temporarly chokes for a moment after playing a bit. How to fix?

This thread is locked; no one can reply to it. rss feed Print
 1   2 
Midi temporarly chokes for a moment after playing a bit. How to fix?
Alex Hanson-White
Member #6,657
December 2005
avatar

Been trying to find an answer to this problem all day. I searched all over this forum to see if there was anything that'd help, but now I come and post this topic.

The problem is, that I can get a midi playing.. but after a while of it playing, it stutters a bit and then chokes(the whole program) for a few seconds, and then it unchokes and then the midi speeds up to catch up to its place.

Any ideas what could be causeing this?

It only chokes when its playing the midi.
And it doesnt just choke once, it does it multiple times the longer you listen to the midi.

Inphernic
Member #1,111
March 2001

Can you post some code (playing parts, main loop, etc)? The whole program choking does not necessarily sound like a MIDI-specific problem, there could be something wrong in for ex the frame limiter, if you have one.

And welcome, awesome pixel art you have there (and on your site). :)

Alex Hanson-White
Member #6,657
December 2005
avatar

thanks, here's some code to help find the problem, hopefully..

1 
2//main part of program
3int main(int argc, char *argv[]){
4 
5 
6 int game_sequence = 0;
7 
8 
9 bool go=true; //used to loop the main section of code
10 
11 //randomizes the random generator
12 srand(time(NULL));
13 
14 //declares the bitmaps
15 BITMAP *buffer;
16 BITMAP *bg_buffer;
17 BITMAP *bg_buffer2;
18 BITMAP *background01;
19 BITMAP *bg_water;
20 
21 MIDI *midi_intro;
22 
23 allegro_init(); //initiates allegro
24 install_keyboard(); //makes keyboard work
25 install_mouse(); //makes mouse work
26 install_timer();
27 install_sound(DIGI_AUTODETECT, MIDI_AUTODETECT, argv[0]);
28 
29 LOCK_VARIABLE(speed_counter); //Used to set the timer - which regulates the game's
30 LOCK_FUNCTION(increment_speed_counter);//speed.
31 install_int_ex(increment_speed_counter, BPS_TO_TIMER(60));//Set our BPS
32 
33 set_mouse_speed(1, 1);
34 
35 text_mode(-1);
36 set_color_depth(16);//sets color depth to 16bit
37 set_gfx_mode(GFX_AUTODETECT_WINDOWED,512,384,0,0);//sets screen to 256x192
38 set_volume(155,155);
39 
40 //loads/creates bitmaps into the variables buffer and image.
41 buffer=create_bitmap(256,192);
42 bg_buffer=create_bitmap(512,384);
43 bg_buffer2=create_bitmap(512,384);
44 background01=load_bitmap("background01.bmp",NULL);
45 bg_water=load_bitmap("bg_water.bmp",NULL);
46 
47 midi_intro = load_midi("intro_temp.mid");
48 
49 clear(buffer);
50 clear(bg_buffer);
51 clear(bg_buffer2);
52 clear(screen);
53 
54 
55 set_grid = 1;
56 anim_frame = 8;
57 anim_frame2 = -2;
58 licky_anim_frame = 0;
59 licky_appear_go = 1;
60
61 
62 //loops the main code that needs to be repeated
63 while(go){
64
65
66 
67 while(speed_counter > 0){
68 
69 if(game_sequence == 0){
70 if(midi_pos < 0)play_midi(midi_intro, 1);
71 titlescreen_background(buffer, bg_water, bg_buffer, bg_buffer2, background01);
72 titlescreen_menu01(buffer, game_sequence);
73 }
74 
75 
76 //menu choice "quit" is chosen
77 if(game_sequence == 5)go=false;
78 
79
80
81 //required for drawing to the screen
82 acquire_screen();
83 //draws the buffer to the screen?
84 
85 stretch_blit(buffer,screen,0,0,256,192,0,0,512,384);
86 //required for drawing to the screen
87 release_screen();
88 clear(buffer);
89 
90 
91 speed_counter --;
92 
93 }
94 
95
96 }
97 
98 destroy_bitmap(buffer);
99 destroy_bitmap(bg_buffer);
100 destroy_bitmap(bg_buffer2);
101 
102 
103 return 0;
104}
105END_OF_MAIN(); //turns off allegro (important)

and here is the frame limit function since you mentioned it..

volatile long speed_counter = 0; // A long integer which will store the value of the
                                             // speed counter. 
void increment_speed_counter() // A function to increment the speed counter
{
  speed_counter++; // This will just increment the speed counter by one. :)
}
END_OF_FUNCTION(increment_speed_counter); // Make sure you tell it that it's the end of the
                                                                 // function

Onewing
Member #6,152
August 2005
avatar

Are you trying to loop the midi? Why not use:

play_looped_midi()

Also, have you tried loading a different midi song to see if it "chokes" as well?

------------
Solo-Games.org | My Tech Blog: The Digital Helm

Alex Hanson-White
Member #6,657
December 2005
avatar

looping is not a problem, it chokes even when it runs the midi once.
I've also tried multiple different midi files, and it's the same with each.

Inphernic
Member #1,111
March 2001

There doesn't seem to be anything wrong with that code (pertaining to this particular problem - you should check whether the bitmap/midi loads were successful though + some other unrelated things :)).

Try examples/exmidi and tests/miditest, do they exhibit the same problem? What compiler/OS/midi synth are you using?

Steve Terry
Member #1,989
March 2002
avatar

Is speed_counter initialized properly?

___________________________________
[ Facebook ]
Microsoft is not the Borg collective. The Borg collective has got proper networking. - planetspace.de
Bill Gates is in fact Shawn Hargreaves' ßî+çh. - Gideon Weems

Alex Hanson-White
Member #6,657
December 2005
avatar

I dont know how to get exmidi.exe to play a midi file, but I downloaded someones allegro game which played midis, and it played fine in their game.

when i run miditest.exe it says microsoft midi mapper under the driver..
my os is winxp, and i use msvc++ 6.0

Inphernic
Member #1,111
March 2001

exmidi.exe <filename>

Alex Hanson-White
Member #6,657
December 2005
avatar

oh ok,

yeah, driver is microsoft midi mapper, and the music plays fine in exmidi.exe

I notice when I change the bps to like 6000 or some big number, it takes forever for the program to quit while it just keeps playing the music with a black screen(when the program shuts down). dunno if that has any significance..

Billybob
Member #3,136
January 2003

Why not just play_midi before the loop, instead of inside of it?

Alex Hanson-White
Member #6,657
December 2005
avatar

i tried that too, it makes no difference.

I tried takeing out the timer function stuff, and it had no difference either.

Arthur Kalliokoski
Second in Command
February 2005
avatar

In Windows9x I've noticed that any huge disk access will cause any midi player stuff to "choke", seems that the multitasker is locked out or something.

They all watch too much MSNBC... they get ideas.

Onewing
Member #6,152
August 2005
avatar

Quote:

The problem is, that I can get a midi playing.. but after a while of it playing, it stutters a bit and then chokes(the whole program) for a few seconds, and then it unchokes and then the midi speeds up to catch up to its place.

Hmmm...reading that again makes me think that something is making the sound driver "think" or the processor or something. At this point, I would just make a small program and just focus directly on the playing the midi without any stuttering. Something like:

int main(int argc, char *argv[])
{
     allegro_init();
     install_keyboard();
     install_sound(DIGI_AUTODETECT, MIDI_AUTODETECT, argv[0]);

     midi_intro = load_midi("intro_temp.mid");
     play_looped_midi(midi_intro, 0, -1); 
     while(!key[ESCAPE]){}

     return 0;
}
END_OF_MAIN();

------------
Solo-Games.org | My Tech Blog: The Digital Helm

Alex Hanson-White
Member #6,657
December 2005
avatar

hm.. odd.

I did a small program:

1#include "allegro.h"
2 
3int main(int argc, char *argv[])
4{
5 
6 MIDI *midi_intro;
7 allegro_init();
8 install_keyboard();
9 install_sound(DIGI_AUTODETECT, MIDI_AUTODETECT, argv[0]);
10 set_color_depth(16);//sets color depth to 16bit
11 set_gfx_mode(GFX_AUTODETECT_WINDOWED,512,384,0,0);//sets screen to 256x192
12
13 midi_intro = load_midi("intro_temp.mid");
14 play_looped_midi(midi_intro, 0, -1);
15 while(!key[KEY_ESC]){}
16 
17 
18 return 0;
19}
20END_OF_MAIN();

and it still has the choking problem..
do you think maybe it's my compiler?

Onewing
Member #6,152
August 2005
avatar

Quote:

do you think maybe it's my compiler?

No. Like you said, without the midi, it runs fine. I doubt that has anything to do with it.

Is it choking in the same parts or is it relatively sporadic?

------------
Solo-Games.org | My Tech Blog: The Digital Helm

Inphernic
Member #1,111
March 2001

Just for the heck of it, try:

while(!key[KEY_ESC]){ rest(1); }

Alex Hanson-White
Member #6,657
December 2005
avatar

its relatively sporadic..
plays for a while, then begins choking, then plays for a while, begins choking again and so forth..

EDIT!:
Inphernic, that fixed it! It doesnt seem to choke up anymore.
Why is that? o_o
Thanks!!

EDIT2:
hm, actually, it doesnt fix it, but it makes it take longer before i encounter the choking..
this sux that i cant post consecutive replies..

Inphernic
Member #1,111
March 2001

The OS' scheduler may throttle your application in order to give some CPU time for other processes. If another process (perhaps even with a higher priority) wants to do something intensive, your program could be affected by that. If the choking seems to be periodic, that might help you to identify the offending process (if any).

Rest(1) effectively introduces a delay of 1ms (due to granularity, more like 10ms) to your program, by which it makes sure that it's not hogging all the CPU time. Considering that adding it had a positive effect, I'd say the problem is indeed related to some sort of throttling. I'm not an expert on scheduling though, so take this with a grain of salt.

Quote:

this sux that i cant post consecutive replies..

You can use the "Send to top" button after a period of inactivity to send this thread right back to the top without making a reply (useful if you just edit your last message). Don't abuse it, though. ;)

Steve++
Member #1,816
January 2002

You will notice that if you play a MIDI in Windows Media Player or WinAmp (just to name a couple), you will not get these problems. That is because those programs fully delegate the MIDI functionality to Windows, which in turn uses its own real-time services to ensure stuttering doesn't occur (except under extreme load). Allegro programs on the other hand take full control of the MIDI sequence and send MIDI events to the OS's MIDI mapper (or its own if that's what you choose) and are therefore at the mercy of the operating system's multitasking. There are other related problems of course, such as the Allegro MIDI routines stripping out XG and GS events, and even some GM events. MIDI is bad enough without it being clobbered by Allegro.

The only solution is don't use Allegro MIDI. Ever.

Inphernic
Member #1,111
March 2001

And by relying on plain MIDI altogether, your songs can end up sounding totally different on different setups. What goes for alternatives: go for XM/IT if file size is a priority, MP3/OGG if quality is a priority (this is a bit of a simplified statement, but anyway).

Simon Parzer
Member #3,330
March 2003
avatar

MIDI is also very bad when it comes to Linux compatibility. In the most cases the only way to play them is using Timidity, which gives very crappy sound at the cost of very much CPU time.

My personal advice: Go for IT! Use Schism Tracker for creating the music (Win32 builds here) and DUMB for playing it in your Allegro program.

miran
Member #2,407
June 2002

:o:o:o:o:o:o @ Schism Tracker

--
sig used to be here

Alex Hanson-White
Member #6,657
December 2005
avatar

hm, i see..

Well, before all of this, i did try to use dumb, but I was unable to make it work, because the instructions to get it incorporated into a project were confuseing for me.

If someone could help me with that, maybe I can try it again..

Corelian
Member #3,376
March 2003
avatar

Quote:

Schism Tracker

Woah! Looks just like Scream Tracker 3. That was a sweet piece of software back in the day.

 1   2 


Go to: