OnAudioFinished not called for USoundWaveProcedural

I have a class extended from USoundWaveProcedural:

// HEADER
UCLASS()
class UMySoundWave : public USoundWaveProcedural
{
	GENERATED_UCLASS_BODY()

	public:
		bool Initialize();
};

//CODE
UMySoundWave::UMySoundWave(const FObjectInitializer& ObjectInitializer) : Super(ObjectInitializer) {}

bool UMySoundWave::Initialize()
{
	uint32 BytesRead;
	uint8 *AudioBuffer = ...;// HERE: GENERATE PCM DATA AND FILL BytesRead
	
	NumChannels = 1;
	SampleRate = 44100;
	Duration = (BytesRead / 2) / 44100.0;
	SoundGroup = SOUNDGROUP_Voice;
		
	QueueAudio(AudioBuffer, BytesRead);
		
	delete AudioBuffer;

	return true;
}

The problem is when I use SpawnSoundAttached with this sound, OnAudioFinished never called.

Did you ever figure this out?

I’ve been struggling with the same issue for the past few days now. I’m considering just putting in a delayed event where the delay = the length of the audio, but that just feels sloppy…

I did the same - timer as a solution/workaround.

The issue is USoundWaveProcedural is still trying to generate audio since nothing told it not to. If you queue all of your audio ahead of time you can bind to OnSoundWaveProceduralUnderflow and check how much data is left to tell the UAudioComponent to stop when you run out of data:

// ...
_soundWave->OnSoundWaveProceduralUnderflow.BindUObject(this, &UMusicPlayer::OnSoundWaveDataUnderflow);
// ...

// Function that gets called on underflow - be sure to make it a UFUNCTION()
void UMusicPlayer::OnSoundWaveDataUnderflow(USoundWaveProcedural* soundWave, int32 bytesNeeded) {
    if (soundWave->GetAvailableAudioByteCount() == 0) {
        // Queue a task to the game thread to stop the audio component
        AsyncTask(ENamedThreads::GameThread, [this, soundWave] {
            // Make sure we are stopping the right sound and it hasnt switched in the mean time
            if (_audioComponent != nullptr && _audioComponent->Sound != nullptr && _audioComponent->Sound.Get() == Cast<USoundBase>(soundWave)) {
                _audioComponent->Stop();
            }
        });
    }
}