MP3/Music and animation timing

Started by James Kay, Fri 23/01/2004 16:51:11

Previous topic - Next topic

James Kay

I'm trying to switch on the visibility of three seperate objects at certain points during the playback of an MP3 (or WAV, whichever works best).

The code I use is:

function room_b() {
PlayMP3File("filename.ext");

if (GetMP3PosMillis()==243){
 ObjectOn(0);
}
if (GetMP3PosMillis()==635){
 ObjectOn(1);
}
if (GetMP3PosMillis()==1166){
 ObjectOn(2);
}
if (GetMP3PosMillis()==5000){
 NewRoom(50);
}
}


However, the objects do not turn on and the music just loops and loops without it going to a new room. What am I doing wrong?
(And is there any way to do this with a WAV file? I'd rather pack my stuff in as few files as possible).

Ta.

J

Darth Mandarb

Not my area of expertise, but maybe put this in the 'repeatedly execute' area.

If this just gets checked when the room loads the music wouldn't be at any of those points (at the start) and then it doesn't perform the check again.

That would be my guess but I'm still pretty new to the scripting stuff!

hope it helps!

])]V[

Scummbuddy

#2
If you are doing an animation, you could have the "footstep sound"  of certain sprites be whatever sound you want them to be, and just happen to have the rest of the music playing in the background.
- Oh great, I'm stuck in colonial times, tentacles are taking over the world, and now the toilets backing up.
- No, I mean it's really STUCK. Like adventure-game stuck.
-Hoagie from DOTT

Scorpiorus

Still a word about the code. First of all, as Darth correctly pointed out, put the if(...) part in room's repeatedly execute. And one more thing - since mp3 processing and repeatedly script run at different frequencies it can't be guaranteed for sure if say AGS plays 635th millisecond and not 636th one while the repeatedly script is being executed. Thus, it's better to use greater-than-equal comparison rather than just equal, like:

int next=0;
function room_*() {
// room's repeatedly execute

if (GetMP3PosMillis()>=243 && next==0){
ObjectOn(0);
next++;
}
if (GetMP3PosMillis()>=635 && next==1){
ObjectOn(1);
next++;
}
if (GetMP3PosMillis()>=1166 && next==2){
ObjectOn(2);
next++;
}
if (GetMP3PosMillis()>=5000 && next==3){
NewRoom(50);
next++;
}


}

The check for the var named next prevents each portion of script to run multiple times.

~Cheers

James Kay

Cheers guys. I'll check it out and let you know if it works.

J

James Kay

No, still no luck.
As there are only 3 objects on the entire screen (it's for an intro logo animation) I deleted the "next++" part, so I can still keep a grasp on what's going on, but no. This is my entire roomscript:



function room_a() {
 // script for room: Player enters screen (before fadein)
ObjectOff(0);
ObjectOff(1);
ObjectOff(2);
 
}


function room_b() {
 // script for room: Repeatedly execute

if (GetMP3PosMillis()>=243){
ObjectOn(0);
}
if (GetMP3PosMillis()>=635){
ObjectOn(1);
}
if (GetMP3PosMillis()>=1166){
ObjectOn(2);
}
if (GetMP3PosMillis()>=4000){
NewRoom(50);
}
}


function room_c() {
 // script for room: Player enters screen (after fadein)
 
PlayMP3File("filename.ext");  
}



What happens now is that all three objects appear simultaneously, too early. And when it goes to Room 50 (my title/menu screen), the MP3 keeps on looping in the background. There is a StopMusic(); command but can't find anything on a StopMP3 type level.
Oddly, the NewRoom command does seem to be "on time", as it were. So why are the 3 objects not behaving properly?

Any thoughts on these two problems?
Any insights greatly appreciated.

J


Gilbert

The reason they appear (seemingly) simultaneously was probably because the period is too short, for milliseconds, 1s = 1000ms, reading your code showed that the objects will all be visible within 1166ms which is just 1.166 seconds, have you checked that the numbers are really set correctly?
To stop the MP3 file, just use StopMusic(), as PlayMP3File() is just an alternate function to play a background music (in MP3 format) if it's not packed in the music pak, copied fropm manual:

Quote
Since normally MP3 files are built into the MUSIC.VOX file, there may be occasions where you want one MP3 (for example, the intro music) to be distributed with your main game rather than the music pack. So, this function allows you to play any named MP3 or OGG file. However, you will have to bundle the file seperately in your game distribution (it is not automatically compiled into the EXE).

James Kay

So can I still use the GetMP3PosMillis() command if I play the file using PlayMusic(nantoka-nantoka);? If so, I'd rather do that and have the file packed in the vox file than having an extra 40 Kb loose file in the bundle.  :-\

Yeah, the timing is short, I know, but that's not the problem (besides, a 1.1 second delay is still easily visible) because the NewRoom command does happen on time.
It should be
show obj 1 - pause - obj 2 - pause - obj 3 - pause - new room
but it is
show all objects - pause - pause - pause - newroom

It boggles the mind....  ???

J

Scorpiorus

Still, try increasing the delay:

if (GetMP3PosMillis()>=1000){
ObjectOn(0);
}
if (GetMP3PosMillis()>=2000){
ObjectOn(1);
}
if (GetMP3PosMillis()>=3000){
ObjectOn(2);
}
if (GetMP3PosMillis()>=4000){
NewRoom(50);
}

Have you spot the delay now? :P

James Kay

Well, okay, I think I recon I know what the problem is.

The GetMP3PosMillis() command is quite inaccurate, as the measurements are very rough. E.g. showing object 0 at 1000 and object 2 at 1500 would show them instantaneously, as if measurements go in steps of a couple of 100 milliseconds.
I have sort of patched the timing together now, but I'm not too happy with it.

Thanks for the input, everybody!

Kweepa

This should probably be documented...

Still, why use the MP3 position when you know the timing from the room enter?

You can do this instead:

// globally
int nantoka_timer = -1;

// player enters screen (after fade in)
nantoka_timer = 0;
PlayMP3File("filename.ext");

// repeatedly execute
if (nantoka_timer >= 0)
{
nantoka_timer++;
int nantoka_millis = (1000*nantoka_timer)/GetGameSpeed();

if (nantoka_millis >= 243)
{
 ObjectOn(0);
}
if (nantoka_millis >= 635)
{
 ObjectOn(1);
}
if (nantoka_millis >= 1166)
{
 ObjectOn(2);
}
if (nantoka_millis >= 4000)
{
 nantoka_timer = -1;
 NewRoom(50);
}
}

Unless the MP3 doesn't actually start on cue...
Still waiting for Purity of the Surf II

Scorpiorus

There is one more very important reason why you better do as Steve suggested. What if the player wish do disable music (or doesn't have a sound card)? Then GetMP3PosMills() always returns 0 and it well bring a mess to the game process. :P

Thus, the GetMP3PosMills() is better to use with another music related commands only so it doesn't have a chance to desync the game.

James Kay

Okay Steve, I concede. You're partially genius too.

I've done it that way now, with the added bonus of not having to use an MP3 file, but a WAV which can be packed into the VOX file.

Thank you everybody!

Gilbert

Actually in that case I'll suggest running a timer (using internal engine timer or gameloop coutning or using the Time functions) when the music starts, that may help.

SMF spam blocked by CleanTalk