How do i make Unity seamlessly loop my background music?

I spent like an hour getting this clip of music to loop seamlessly and when I finally got it, I put it into my game as background music that looped. But then I noticed all my work to make it loop seamlessly was for nothing, because what it looks like is that Unity is adding a split second of blank audio at the beginning of my mp3 file, so I have an obvious pause in the loop that sounds terrible. How do I prevent Unity from screwing up all my work and not adding the blank audio at the beginning?

I can only give you my noob experience.

You have to save your audio as a .wav (for some reason, a small amount of data is added to the beginning/end of the MP3, I am assuming for ID tag and track info, image etc). Then in the Inspector settings of the sound, select Audio Format : Native (WAV)

Create an empty GameObject.

Add an Audio Source component.

In the Inspector, Select Play on Awake and Loop.

Finally drag-and-drop your audio into Audio Clip in the Inspector.

MP3 is no good for seamless looping, because it indeed messes up the timing, inserting a small pause in the beginning of the file. This has nothing to do with tags (they are inserted at the end of the file, and would not be interpreted as audio data anyway).

Try using WAV or Ogg Vorbis, because these formats keep things loopable.

I wrote up a post that explains how to create seamless looping files and convert them for in game use! It should answer any questions you have :slight_smile:

http://www.playdotsound.com/portfolio-item/tutorial-how-to-create-seamless-looping-music-and-sfx-files-for-video-games/

Maybe this is not relevant anymore since Unity can compress WAV files directly to very compact seamlessly looping OGG files and can’t see any benefit using MP3s nowadays, but I actually were able to loop MP3 files surprisingly well with a script I wrote. :slight_smile:

 /// <summary>
/// Trims silence from both ends in an AudioClip.
/// Makes mp3 files seamlessly loopable.
/// </summary>
/// <param name="inputAudio"></param>
/// <param name="threshold"></param>
/// <returns></returns>
AudioClip trimSilence(AudioClip inputAudio, float threshold = 0.05f)
{

    // Copy samples from input audio to an array. AudioClip uses interleaved format so the length in samples is multiplied by channel count
    float[] samplesOriginal = new float[inputAudio.samples * inputAudio.channels];
    inputAudio.GetData(samplesOriginal, 0);

    // Find first and last sample (from any channel) that exceed the threshold
    int audioStart = Array.FindIndex(samplesOriginal, sample => sample > threshold),
        audioEnd = Array.FindLastIndex(samplesOriginal, sample => sample > threshold);

    // Copy trimmed audio data into another array
    float[] samplesTrimmed = new float[audioEnd - audioStart];
    Array.Copy(samplesOriginal, audioStart, samplesTrimmed, 0, samplesTrimmed.Length);

    // Create new AudioClip for trimmed audio data
    AudioClip trimmedAudio = AudioClip.Create(inputAudio.name, samplesTrimmed.Length / inputAudio.channels, inputAudio.channels, inputAudio.frequency, false);
    trimmedAudio.SetData(samplesTrimmed, 0);

    return trimmedAudio;
}