[SOLVED] Not receiving orxEVENT_TYPE_SOUND events

edited October 2011 in Help request
So, I'm listening for several different types of events in my game. The relevant callback-initialising code is as follows:
orxSTATUS orxFASTCALL App::Init() {
  orxLOG("*** Main app starts! ***");
  
  ..

  // event handlers
  orxEvent_AddHandler(orxEVENT_TYPE_ANIM, App::AnimEventHandler);
  orxEvent_AddHandler(orxEVENT_TYPE_INPUT, App::InputEventHandler);
  orxEvent_AddHandler(orxEVENT_TYPE_PHYSICS, App::PhysicsEventHandler);
  orxEvent_AddHandler(orxEVENT_TYPE_SOUND, App::SoundEventHandler);

  return orxSTATUS_SUCCESS;
}

..

orxSTATUS orxFASTCALL App::AnimEventHandler(const orxEVENT *currentEvent) {
  orxLOG("Anim event!");
  return orxSTATUS_SUCCESS;
}


orxSTATUS orxFASTCALL App::InputEventHandler(const orxEVENT *currentEvent) {
  orxLOG("Input event!");
  return orxSTATUS_SUCCESS;
}


orxSTATUS orxFASTCALL App::PhysicsEventHandler(const orxEVENT *currentEvent) {
  orxLOG("Physics event!");
  return orxSTATUS_SUCCESS;
}


orxSTATUS orxFASTCALL App::SoundEventHandler(const orxEVENT *currentEvent) {
  orxLOG("Sound event!");
  return orxSTATUS_SUCCESS;
}

So far they're all working correctly, except for the SoundEventHandler. When my animations tick by, I see "Anim event!"; when there's input or a physical collision, I see those respective messages as well. However, when I play a sound, and when it finishes, there's no message whatsoever.

I can repeatedly poll the playing sound, and I can see that it does change from orxSOUND_STATUS_PLAY to orxSOUND_STATUS_STOP. But this doesn't seem to be signaled by an event to my main App:SoundEventHandler.

I'm at something of a loss.

Comments

  • edited October 2011
    Oh, and I'm working from the SVN build of Orx.

    Are there known audio issues?
  • edited October 2011
    Mmh, weird. I'll try to check that tonight or tomorrow. Did it work for you in the sound tutorial?
  • edited October 2011
    Yeah, the 06_Sound tutorial is working just fine; I can see the Sound events coming in.

    This is very, very weird. And I assume it's a problem on my end =

    ... I'm writing a stand-alone application---could that be the problem? I mean, could the audio libraries be having trouble in this case?
  • edited October 2011
    Perfect timing!

    I just finished testing on my side and it looked fine with a wav sample (kept in cache or not).
    I haven't tried in a stand alone, but that'd be surprising. I'll try that on my side later today and will let you know if I find something.
  • edited October 2011
    I'm going through the Orx SVN code to see where the sound events are being thrown. All I see is a bit in orxSoundPointer.c, in the sound pointer Update() function. Is this correct?
  • edited October 2011
    Yeah, that might be something. orxSoundPointer_Update() is the only function in the Orx library that does orxEVENT_SEND(orxEVENT_TYPE_SOUND,...).

    I'm assuming orxSoundPointer_Update() is set as a callback somewhere? However, if I just add a debugging orxLOG() to the function, it never gets called. Is this normal?
  • edited October 2011
    Riiiight...okay, figured it out.

    I was using orxSound_Play() to play my sounds.

    The orxEVENT_TYPE_SOUND is only sent when I use orxObject_AddSound().

    Made the switch, and it works.

    It should have been obvious, but once again I made assumptions; in this case, that orxSound_Play() and orxObject_AddSound() would have the same effect.

    Out of curiosity though, why does one cause the event to be sent and the other does not?
  • edited October 2011
    I was about to ask that this morning, you were faster than me again. :)

    The events are sent only by the SoundPointer, which is the holder structure referenced by objects. It was done this way to be symmetrical with other events, such as the anim ones and also because we don't have any access to the object from the sound itself, only from the SoundPointer.
    Lastly, we try to only fire events for things that orx automates behind the user's back, to let him know what's happening, and not for direct calls (when you call orxSound_Play() directly we assume that you know a sound is going to be played :)).
    That being said, I'll change the stop event so that it'll be called on remove too, so as to be symmetrical.
  • edited October 2011
    Fair enough, I know what it's like when you want to have some sort of interface consistency across your API. There's always weird exceptions that can be hard to work around.

    In this case---at least on this project---I like to be able to fire off sounds and then just wait for the callback that they've ended, rather than continually polling them every update() loop. And that's even though I fire off the sound myself. But opinions can differ, I imagine.
  • edited October 2011
    Well, if you add the sound through the object or soundpointer API you should get the notifications for sure.
    If you use the low level sound API, it gets more tricky and I'm afraid you'll have to poll the sounds yourself. But in that case, is there any reason why you wouldn't use the higher level API?
    Also if you want to keep your processing in one place, you can shoot the start/stop events yourself.

    Orx's event system was designed to be as simple as possible and to allow both notifications and queries. You can also add as many custom user event types/IDs as you want (actually some plugins are doing that behind the scene in order to communicate without having a generic channel set in orx).
  • edited October 2011
    Ah, I gotcha. In my case, I don't really have any central object to which I'd be attaching the sound, so I figured playing a sound directly would be fine.

    I suppose instead, I could just add the sound to any random object in my scene (it's just one screen) and making sure there's no attenuation set on it.
  • edited October 2011
    That would definitely work.
    I'm usually even more sneaky and create an empty object to serve as container for my music/object-less sounds.
    I think all my projects have an empty section called Dummy just for this purpose. :)
  • edited October 2011
    Yeah, that's probably what I'll be doing for future projects.

    For this one though, since I couldn't get the callback to work for a while, I was indeed just continually checking for orxSOUND_STATUS_STOP on whatever sound I need. It's not so bad in this case, since I'm never polling for more than one sound at a time (The American Dream is just a collection of small minigames, after all). But next time I'll definitely have the dummy objects.

    Thanks again!
  • edited October 2011
    Hmm. Hate to reopen this one, but it seems like once the program is actually on the Android device, Orx is throwing orxSOUND_EVENT_START messages, but not orxSOUND_EVENT_STOP ones, even though I'm using orxObject_AddSound() to play them. A consequence of Android's audio architecture?
  • edited October 2011
    Is that with the latest SVN version? Does it happen only on Android? (maybe I broke the sound event for all the platforms! :)).

    I don't think sound events could behave differently from one platform to the other, but again my knowledge of the Android version is extremely limited. I'll check the code tomorrow.
  • edited October 2011
    Yeah, I checked the identical code in the PC version and it works: both orxSOUND_EVENT_START and orxSOUND_EVENT_STOP are received by the sound event handler.

    However, in the Android version (with both the Debug and Release Orx libraries---orxd and orx), only orxSOUND_EVENT_START is received; orxSOUND_EVENT_STOP does not get caught at all.
  • edited October 2011
    Have you compiled the orx Android library yourself, btw, in case it could be outdated?
    Just running wild guesses there, I really don't know much about that whole platform, and I should probably shut up while waiting for someone that knows how it works to reply, such as Lydesik or Faistoiplaisir. :)
  • edited October 2011
    Yeah, I compiled it according to the instructions in the wiki, and I just checked that I'm still up to date with the SVN.

    Probably just a single line of code needs to be altered to get orxSOUND_EVENT_STOP to fire. Or at least that's what I'm hoping.
  • edited November 2011
    Hi,

    For now, I never used sound on android, but I took a look at the module implementation. I think I found the problem (just by looking the code), but I don't know what's the solution.

    We need help from Lydesik for this.

    I explained what I see :

    => To send event, orx call a XXX_GetStatus() function.
    => This function never return stop, in android, when an internal variable called bIsUsingMediaPlayer is set to false.
    => This variable is initialized to false when the sound is loaded with the module function : orxSoundSystem_Android_CreateFromSample
    => And finally, this function seems to be call when the sound definition use "Sound = ..." in the config. If the sound use "Music = ..." in the config, the sound is load by the function orxSoundSystem_CreateStreamFromFile that init the bIsUsingMediaPlayer to true ...

    So since Lydesik have wrote this code, I think he can explain why there's 2 methods to play sound on Android (media player or not) ... I will ask him about that.

    I hope I didn't make a mistake be reading the code, I haven't test nothing ^^

    Cheers.
  • edited November 2011
    Huh, well look at that. I changed my config file from
    Sound = ../path/to/sound
    

    to
    Music = ../path/to/sound
    

    ...and it works! I get the orxSOUND_EVENT_STOP message as expected! We should probably investigate why there's the difference in the first place, but at least this solves the problem for now.

    Thanks!
  • edited November 2011
    Hi all,

    ok sound implementation on android (non-native) is flaky, but mainly because of android platforme...

    so there is two kind of "sounds" in orx, streams, and samples

    streams are used for music, because music file are huge and can't be loaded completely in memory for playing, on android it's using the MediaPlayer framework service. the issue is that there is a delay between the call to play function and when it's actually coming out of the speakers.
    orxSOUND_EVENT_STOP is fired because i can query this service to check if the file is playing or not.

    samples are used for SFX, they are small, and can be kept in memory to play them ASAP. on android SFX are using the SoundPool API.
    there is two issue with this API.
    1) when you first ask a sound to be played from orx, orx will try to first load it, and immediately play it. Unfortunately, on android the loading is asynchronous, and when orx will ask to play it, the sample will not be ready (so you miss the first play). the workaround is to pre load samples before using them...
    2) this API doesn't allow me to query if a sample is still playing or not... so currently, a sample status is never set to STOP, thus the event is not send... I could try to hack a workaround for this, but it wont be nice...

    hope it explained your issue

    Lydesik
  • edited November 2011
    Thanks for all the details, Lydesik!

    Mmh, I don't see many workarounds beside storing the sample's duration and start of play and doing a time check to see if the sample should be over.
    Even in the case where sounds are not started right away because they're not loaded, we can set a load completion callback to init (or reset?) the start timer when loading's done.

    Did you have something else in mind?
  • edited November 2011
    well currently orx on android targets android 2.1 and up, and on this version I don't even have a callback to know when a sample is loaded and ready to be played...

    I could drop anrdoid 2.1 support and move to android 2.2 where such callback is available (android 2.1 is still installed on about 12% of devices)

    or try some Java magic to detect on which android version orx is running...
  • edited November 2011
    Ah I see, I missed the API level 8 label in the corner of the function description in their doc. Subtle.

    Is that really that non-trivial to get the version of Android used by a device? Sounds to me like one of the fundamental requirements of any OS.
Sign In or Register to comment.