Time/duration functions on Synth components - weird behaviours

So I’ve been testing SynthSamplePlayer and GranularSynth, I’ve noticed some weird things with functions like Get Current Playhead Time / Get Current Playback Progress Time, Get Sample Duration, and the seeking functions.

  • The Return Value on Get Current and Get Duration functions seems to be truncated as integer, so even when printing out the value on the tick, the value itself only updates every second. Not sure if Scrub Mode is related to this, but it being on or off doesn’t seem to make a difference.
  • Seek functions like Seek To Time and Set Playhead Time don’t work properly if the sample is stereo: so if I’m using a stereo soundwave that’s 12 seconds long, if I want to pick a random point within that whole file I actually need to get a random float between 0 and 24, otherwise only the first half of the file is used.

On a similar note, is there an option to make SynthSamplePlayer looping? As of now, if I’m randomly moving the seek time and the playhead reaches the end of the file, the sampler just stops playing.

It would also be nice to be able to set soundclass and submix of a synth componennt via BP node, same as it’s currently possible with attenuation settings.


I encountered the same problem with GetCurrentPlaybackProgressTime, returning a float truncated to integer instead of a proper fraction. It seems to me the problem may be in Engine/Source/Runtime/AudioMixer/Private/DSP/SampleBufferReader.cpp, on line 375:
PlaybackProgress = (float)(WrappedCurrentFrameIndex / BufferSampleRate);

Written this way, the integer result of the division is converted to float after the fractional part is already lost. If I’m not mistaken, the correct version would look something like:
PlaybackProgress = (float)WrappedCurrentFrameIndex / (float)BufferSampleRate;

I’m just trying to get Git and stuff working on Windows (which is a pain, but Oculus does not support Linux) so I can test the change. I’m not sure if I should make a pull request in case it works, though – it looks like the SampleBufferReader may be used all over the place and who knows – the truncation may be intentional and expected by other code using the function…

Hi @H-S_ and @AlessioMellinaNT, thanks for bringing this to our attention. @Ethan.Geller has submitted a fix to our Dev-Audio stream. You are correct in finding this truncation issue, the fixed code is:

PlaybackProgress = ((float)WrappedCurrentFrameIndex) / BufferSampleRate;

This should properly return a float, though explicitly casting both integers to floats should also work.

The SampleBufferReader is only used in the Synth Sample Player and the Granular Synth, so there shouldn’t be any wider implications.

@dan.reynolds Great, thank you for forwarding it to proper places. :slight_smile: Last few days I have been working on my project with the fix in place and it seems to be working well, with no side effects.

That said, I encountered another … well, let’s say unexpected behavior. I’m not sure if it is intentional or not (since there is not really much to be found in terms of documentation for Synth Sample Player), but it seems that all sound waves, no matter their actual sample rate, are replayed at 48 kHz. For sounds sampled at 44.1 kHz the change in pitch is not that big (I didn’t even notice until the reported playback time went out of sync with my “real time clock”). But for sounds sampled at 22k it is hard to miss.

Is Synth Sample Player expected to be playing sound waves originating from files in the Content Browser? Or is it to be used only as a “backend” for, say, the Modular / Granular Synth or something? (No idea, I am still trying to figure out which component is supposed to be used for what… :slight_smile: ) If the second case is true, using the “native” 48 kHz sample rate probably make sense.

In case this is expected behavior, is there any way to get the sample rate of a given sound wave, preferably using only blueprints? I could simply correct the playback speed by setting pitch to n / 48000, where n is the sample rate for given sound wave. But it seems the only component that can report anything about sample rate is Media Player, which does not seem like something I would like to use just to get this one number.

(As for my motivation: I am using Synth Sample Player to play sound waves directly, because I found no other audio component that provides the playback progress feedback. The audio timing in my project is quite essential, so just starting a timer along with the playback simply does not work – any drift or starting offset would mess things up. Using the time progress as a primary “clock source”, I can guarantee everything stays in sync, no matter what happens.)

So, I tried to add a custom “getSampleRate()” to the Synth Sample Player BP interface and get the information from the loaded SoundWave, but all I got in return so far was “-1”. So no luck there. But while trying to work with manually entered pitch correction, I noticed another problem that supports the continued use of the “beta” label. :slight_smile:

When replaying a sound wave at lower pitch, I could often hear a popping or crackling sound. It only happens with stereo sounds and only if the waveform is very close to clipping. I managed to get a very “good” result with the linked file and a simple setup with pitch set to 0.65 (tested using version 4.20.1 from launcher). Small changes to the pitch value result in different popping patterns (or no popping at all). Playing around with buffer sizes and volume did not appear to change the result in any way.…yORD0DBhX87AQk

(I realize this thread is now starting to stray away from the original timing-related issues; I can start a different thread if that would be preferred.)