Add support for loop points in sounds

As a Roblox developer, it is currently too hard to create loop points for sounds. Although Roblox does have looping, it’s extremely limited and does not recognize the loop points in an audio file or allow developers to set them.

What are loop points?


We all know what a sound loop is, once the end of the sound is reached, it’s replayed. Pretty simple.

But this type of looping doesn’t always work. What if we want an intro to our sound? Or what if we want an outro after X loops or another condition?

This is where loop points come in! Loop points allow us to define when a loop “begins” and a loop “ends”, excluding those parts from the loop!

The sound starts with the intro, and once it reaches the end of the loop, it goes back to the start of the loop, eventually being able to end with the outro, all completely seamlessly. This is extremely useful for certain sound effects and background music, allowing developers to get more creative with their sound design and composing.

How are they stored?


In reality, there’s no “real” standard to storing the loop points, even within the same format. In the file formats Roblox allows…

  • .wav has no standard as far I can tell, it’s typically used for short sounds that rarely loop or storing raw sound data for later processing.

  • .mp3 also has no standard as far as I can tell, as encoders tend to introduce a silent padding in the sound, making these calculations too imprecise. See this topic for more details.

  • .ogg, which is the most common filetype used in games and other software, doesn’t have a standard in its specs either, however, my research suggests that a de facto standard exists across game engines.
    It appears that game engines typically get the loop data from the file’s metadata tags. There’s two common variations of this practice:

    • LOOPSTART and LOOPEND tags: LOOPSTART indicates in which sample the loop starts, LOOPEND indicates in which sample the loop ends.
      image

    • LOOPSTART and LOOPLENGTH tags: LOOPSTART still indicates in which sample the loop starts, but LOOPLENGTH indicates the length of the loop in samples.
      image

    Additionally, some engines prefer to leave an exposed API for developers to set LoopPoints, but usually still allow developers to read sound file metadata, keeping the practice of storing the points in metadata like this common.

Examples of ogg metadata or engine APIs being used for loop points: Ogg LOOPSTART | Forum, Looping OGG Files for use in RPG Maker & Others :: rpgmaker.net, seamless looping for ogg supported? — dengine Forums, Audio loop - The Doom Wiki at DoomWiki.org, BGM loop points, How To: Looping music files - Moondust Wiki, Looping a Sound - Valve Developer Community, https://forum.unity.com/threads/defining-loop-points.675580/.

The problem


Sadly, Roblox doesn’t recognize those metadata tags in an .ogg file nor does it allow us to set loop points in-engine, meaning that looping always spans the whole sound.

Edit: After some testing, I’ve discovered that the workaround below isn’t practical. Roblox’s API simply doesn’t provide timings precise enough to make a seamless transition.

The only way to get around this is to:

  1. Not use Roblox’s native looping and instead store the start and ending position of the loop somewhere (whether that is in attributes or inside of a script).
  2. Add a buffer after the ending point that is exactly equal to the first few seconds of the loop segment
  3. Every frame, check if the sound’s TimePosition is equal or above to the loop end point, then subtract the Current TimePosition by the loop’s length TimePosition -= (LoopEnding - LoopStart).

The “buffer” is necessary because Lua simply can’t run fast enough to detect the loop ending being reached before playback goes past it (this is only possible by the engine responsible for playback!), not including it would result in a noticeable silence (or the sound’s outro) being heard before the sound looped. This method also demands more manual work, as you’d have to hardcode your time positions in your code or datamodel instead of just configuring it while exporting the sound.
Sadly, as you have to include a buffer, certain outros that play shortly after the loop simply aren’t possible, as they would interfere with it.

Edit: After some testing, I’ve discovered that the workaround below isn’t practical. Roblox’s API simply doesn’t provide timings precise enough to make a seamless transition.

You can also try splitting the sound into an intro and a loop, but this would still require a buffer for the intro sound and would force developers to upload two sounds, impacting their limited sound upload quota. It’s actually a worse solution!

Roblox should standardize and check for sound metadata tags that determine how a looped sound should be played. Alternatively, Roblox could give us access to the sounds’ metadata tags in-engine and allow us to set the loop points in-engine (ex: Sound.LoopStart, Sound.LoopEnd), essentially having the same effect but making the developer responsible for picking the format in which they store the data in. Roblox should follow the precedents set by existing engines.

If Roblox is able to address this issue, it would improve my development experience because creating loop points for sound would not require hacky workarounds and hardcoding that doesn’t fit all usecases. that doesn’t work at all. Outros would be possible, no superfluous audio uploads would be needed and sound effects and background music with a beginning, middle and ending would be more feasible and easier to implement. It’d also allow for better integration with sound editing software (Audacity, FL Studio, Reaper, etc…), as they already include easy ways of inserting these fields into the metadata.

FMOD’s API (the audio engine Roblox uses) already has a method for setting the loop points of a sound, so it really make no sense that this functionality is missing.

58 Likes

I second this.
Here’s a better visual example of loop points in FL Studio:
image

4 Likes

While I do agree with reading data off an OGG or MP3 file for loop points. I believe a LoopRegion NumberSequence object is also useful for third-party sounds that dont have loop points placed on them.

4 Likes

Definitely. This is the kind of functionality that should allow us to associate the metadata directly with the sound files we uploadd while also allowing in-engine flexibility for 3rd party assets that weren’t uploaded by us.

Totally support this feature.
In programs like FL Studio you can also set looping points but Roblox doesn’t recognize them.

I support this! Im extremely limited already to what you can do to audio in roblox but having loop points with seamless transition would make it possible for me to have multiple engine rpms in one sound and seamlessly transition between them