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:
Source->Init (AudioDevice.cpp:1943) to initialize a new source with the wave instance.
After a successful call to
FSLESSoundSource::Init sets the
WaveInstance member of the source to
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.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.
May 20 '16 at 02:51 PM
in Bug Reports