OK, here's the situation:
I have written a small app to play MIDI files. The primary goal is to keep sending music out on time. A secondary goal is to update a few objects in the window. There is a button with SMPTE time as the text and another button with music time. There is also a fuelgauge gadget that shows the progress as the song plays.
All of this works great as long as intuition is not too busy. But if the user starts moving or resizing windows on the screen, the program is "locked out" until the user lets go of the resize.
I understand the problem, and I would be happy to stop updating the window during these times, but the music should continue uninterrupted.
I tried enclosing the gadget update code with AttemtLockLayerRom(window->RPort->Layer) and a similar UnlockLayerRom at the end, in hopes of just skipping all graphics while I am locked out. This seemed like a good idea, until I realized that I needed Intuition to do updates WHILE I was holding the lock.
I'm thinking of bypassing Intuition and rendering the text directly from IGraphics calls, but that would still leave the FuelGauge out of the loop.
Is there a way to gracefully avoid getting locked by Intuition short of rewriting it all myself with graphics library?
Thanks In Advance,
Lyle Hazelwood
Use CreateNewProcTags() to detach the replay routine from the GUI. To update the GUI simply send a message from the replay task to the GUI task. If the GUI is busy it just does not react on the message but the replay task can continue playing.
Thank You!
LyleHaze
Just a follow-up. (or maybe follow-back??)
Running the player as a background process worked great.
I took a little extra time to manage the interprocess communication. Since both processes have CAMD ports open, I even used as many "standard" MIDI transport commands as possible. So now the basic stuff like Start, Stop, Continue, and song position are handled in the standard MIDI way, using CAMD links to carry the messages.
I did find one unrelated problem though. I'll mention it here in case it helps someone else.
I ran the priority of the background process pretty high (+30). Of course I wanted to make sure my timing stayed solid. The program sent the MIDI stream out through CAMD, and on to the USB MIDI driver on it's way out to my USB-MIDI interface.
It turns out that this created a really unstable system. I knocked myself out for a few days trying to track down what the problem was. I tried LOTS of different things before it occured to me that it might be priority related. Once I backed the program priority down to a level below the USB stack, everything got solid again.
Is there a "standard" for where program priorities are expected to be?
And again, thanks for telling me to try a child process. Works great, and should be portable to other midi player projects as well.
Lyle
LyleHaze
The Amiga's multitasking is very basic. The scheduler always schedules tasks with a higher priority before those with a lower priority. As a consequence if you create a high priority task which uses a lot of CPU time, normal priority tasks will stutter or hang. Only tasks with equal priority share the CPU.
For an application you should stay between -1 and 1. -1 for tasks which need a lot of CPU time. 1 for tasks which need to react very quickly but use next to no CPU time. 0 for everything else.
It would be desirable to implement a new scheduling system with variable priorities like Executive does, but that hasn't happened yet. Although with 30 you would be outside of the range Executive uses, too.
I had a quite similar problem with InsanePlaya back then. Very high priority made the system unstable/unusable, "normal" priority locked the player process in certain situations. I found, that a priority of 10 is usable for such tasks. Not too high to block input.device and friends, and not too low to be blocked if theres heavy GUI load (like some MUI/ReAction classes do).
Coder Insane-Software
www.insane-software.de