x

Search in
Sort by:

Question Status:

Search help

  • Simple searches use one or more words. Separate the words with spaces (cat dog) to search cat,dog or both. Separate the words with plus signs (cat +dog) to search for items that may contain cat but must contain dog.
  • You can further refine your search on the search results page, where you can search by keywords, author, topic. These can be combined with each other. Examples
    • cat dog --matches anything with cat,dog or both
    • cat +dog --searches for cat +dog where dog is a mandatory term
    • cat -dog -- searches for cat excluding any result containing dog
    • [cats] —will restrict your search to results with topic named "cats"
    • [cats] [dogs] —will restrict your search to results with both topics, "cats", and "dogs"

Android audio: Crash if USoundWave::GeneratePCMData returns 0 samples

We have a custom USoundWave-derived asset which can potentially return 0 from GeneratePCMData if it has not uncompressed the data in time. This tends to happen just the first couple of times after the asset is loaded. On Windows this does not cause any noticeable issue, but when deploying to Android it results in a crash.

Is it acceptable for this method to potentially return 0? Looking at the various implementations in the engine, it seems that it is.

Here's what I've found from debugging:

FAudioDevice::StartSources calls Source->Init (AudioDevice.cpp:1943) to initialize a new source with the wave instance.

After a successful call to CreatePlayer(), FSLESSoundSource::Init sets the WaveInstance member of the source to InWaveInstance.

If the following Enqueue call fails* (see below), then DestroyPlayer() is called, which nulls out the various SL_ interfaces on the source, then Init returns false. Note that the WaveInstance member of the source remains non-null.

WaveInstance->StopWithoutNotification() is called (AudioDevice.cpp:1957).

In the next call of FAudioDevice::Update, the sources are iterated through and IsFinished() is called on each one (AudioDevice.cpp:2015).

This will call IsSourceFinished() if the WaveInstance member of the source is non-null (AndroidAudioSource.cpp:568). Even though our source failed to initialize, its WaveInstance member retained a valid pointer.

FSLESSoundSource::IsSourceFinished dereferences the SL_PlayerPlayInterface interface pointer (AndroidAudioSource:549), which had been nulled out in DestroyPlayer, resulting in a crash.


*I'm seeing the following in the log at this point:

 05-16 22:27:26.784  7968  7992 W libOpenSLES: Leaving BufferQueue::Enqueue (SL_RESULT_PARAMETER_INVALID)

I suspect this is failing as a result of GeneratePCMData returning 0, which is causing AudioBuffers[0].AudioDataSize to be set to zero, and I'm guessing that is what is considered the invalid parameter. Regardless, I don't think a failure here is intended to result in the crash that follows.

Product Version: UE 4.11
Tags:
more ▼

asked May 20 '16 at 02:51 PM in Bug Reports

avatar image

kamrann
2.1k 83 33 119

avatar image Minus_Kelvin STAFF May 20 '16 at 05:22 PM

Is it acceptable for this method to potentially return 0? Looking at the various implementations in the engine, it seems that it is.

Yeah, I think a similar crash was reported on PC and we just allowed the 0-value return and early outed.

(comments are locked)
10|2000 characters needed characters left
Viewable by all users

1 answer: sort voted first

Hi kamrann,

We have not heard back from you in a few days, so we are marking this post as Resolved for tracking purposes. If you are still experiencing the issue you reported, please respond to this message with additional information and we will offer further assistance.

Thank you.

more ▼

answered May 26 '16 at 12:46 PM

avatar image kamrann May 27 '16 at 12:03 AM

I just took the comment from MinusKelvin as confirmation that it probably is a bug, not as a solution. If it was intended as the latter, I don't follow.

As far as I can see, there is a fundamental issue with the Android engine code that will inevitably lead to a crash if GeneratePCMData returns 0, as detailed in my post.

This is currently forcing us to use a blocking call as a workaround on Android for our audio plugin, resulting in an unacceptable hitch when playback begins.

avatar image Minus_Kelvin STAFF May 27 '16 at 01:07 AM

Hi kamrann,

I'm not our android platform programmer so am not completely familiar with the android API. Instead of blocking, have you tried simply writing out 0s on the GeneratePCMData() callback in the case that the sound is not ready to play yet?

avatar image kamrann May 27 '16 at 07:28 AM

I hadn't thought of that, I'll give it a go. Thanks.

Can I ask that this is left open and investigated though, since I'm fairly sure there is an issue with the code.

avatar image Minus_Kelvin STAFF May 27 '16 at 10:19 PM

Well, I'm working on a multi-platform mixer that will theoretically replace all this duplicated code everywhere -- so hopefully this problem (and many many many others like it) will be reduced to ONE implementation... :)

(comments are locked)
10|2000 characters needed characters left
Viewable by all users
Your answer
toggle preview:

Up to 5 attachments (including images) can be used with a maximum of 5.2 MB each and 5.2 MB total.

Follow this question

Once you sign in you will be able to subscribe for any updates here

Answers to this question