Introloop - Easily play looping music with intro section

Demo, Installations, Scripting Ref., FAQ : Introloop - Unity Plugins by Exceed7 Experiments
Change log : Changelog | Introloop
Asset Store Link : Introloop | Audio | Unity Asset Store
Contact : Post on this thread or mail to 5argon@exceed7.com or Discord Exceed7 Experiments

Less than 1 minute explanation of what it is :

Get that charm of a polished game. Adds huge value to music. Directs player’s feel with an intro. Gives every song a memorable and immersive feeling which can’t be put in an OST.

Let’s recall memorable moment from favorite games you have played. A destined fight with arch rival? Roaming overworld map for the first time? An opening stage that really hooks you that you can’t put down the joystick?

Wondered why they stuck so well in your memory? The answer is music intro and I am going to make you realize that it is important. I think I am not the only one who noticed this so I made Introloop for the person who cares about his own game soundtrack :smile:

Many commercial game music has certain charm when you are listening to it in game because they’re programmed to have a nice intro that sets the mood of that particular scene, before transitioning seamlessly to a music loop, never having to play the intro again. This is the source of immersive feeling you never get when you listen to the song again in an OST.

In Unity if you select “Loop” in an AudioSource, the song will loop to beginning when it reaches the very end.

With Introloop, you can specify 2 time point “Intro Boundary” and “Looping Boundary” in your audio. Playing with this plugin, it will now loop back to Intro Boundary when it reaches Looping Boundary, effectively make the section before Intro Boundary an intro section that plays only once and the rest will be looping.

Introloop is also natural for the composer. Almost all DAW has a “loop bracket” function. You can start playing before the left edge of the bracket, but once the playhead is inside and finally arrives at the right edge then it loops back to the left edge.

Introloop make the composer very comfortable as he see what the game would play like what he can preview on the DAW. Exporting the song is easy as he can export the whole song without any special care like having to export twice to cut them up for the developer.

Advantages

  • No need to cut the actual file into 2 parts.
  • Because of that you can use any compression (like OGG) without fear of messing the precision at the head and tail of audio file. Feel free to utilize the Unity’s compression quality slider - and any other audio settings built-in. It even works with Streaming load type.
  • It is easy to experiment and adjust the loop point right in Unity. In a splitting clips solution you will have to cut the music over and over again until it is seamless enough.
  • Updating music from your composer is easy, as long as the song structure is the same you can just replace the whole music and use the old boundaries.
  • Automatic audio memory releasing at appropriate time. Perfect for mobile project. This is not the case in Unity as even after the song has stopped it will be still in your RAM.
  • Supports pause, resume, fade in, fade out and even cross fading between introlooping audio.
  • Built in pop/clicks reduction when stopping the music suddenly.
  • An asset-based design allows you to have more metadata per audio, such as a default volume. This is not possible in an imported AudioClip.
  • Supports time operation such as seeking or starting at a different time. Note that in Introloop the time is theoretically infinite. These operations are more complex than same thing you usually see in other audio API.
  • You could specify a constant pitch for each asset file. The loop scheduling is still dead-accurate.
  • Route the entire plugin to your game’s AudioMixerGroup for your own higher level control. Casting epic spell and wanted to duck the BGM down? Just route to your mixer and use Unity mixer’s ducking feature on it.
  • Modern plugin design. It is in a proper UPM (Unity Package Manager) shape with package.json, with a proper Assembly Definition Files, namespaced properly, internal utilized effectively, asset-based design will not clutter your scene with anything, and it came with no other assortments of audio features.
  • The license purchase came with full source code.

It is a common practice used in many commercial games. Intro adds huge value to music, turning into a powerful tool for directing player’s feel and blends more into gameplay.

It’s not just about random battles, any feeling you would like your player to feel, use music intro to direct him/her to that direction right from the start then keep it going with your gameplay.

See real examples from commercial games and try out the demo in the website below.
Introloop - Unity Plugins by Exceed7 Experiments

Feel free to ask me any question about Introloop. Criticisms, suggestions are all welcomed as I wanted to know what you guys want. Thank you!

Cool.
Can we expect a smooth loop without any noticable “cracks” when it jumps from end to startpoint?
In my experience this is the hardest point to solve.

Yes! You can expect it as long as your 2 time point is precise enough. The timing is achieved by not the normal game time nor coroutine but by AudioSettings.dspTime, AudioSource.PlayScheduled, AudioSource.SetScheduledStartTime and AudioSource.SetScheduledEndTime internally to ensure this.

I have provided the demo in this page so you can test the seamless-ness. Or alternatively if you don’t have the PC now, download this game to your mobile phone and hear if you notice any cracks or not. (The title screen already is using Introloop)

Is there a way to change a track’s volume in real time? In my game, the player can change global background music volume in the option screen. It’d be nice if they can hear the change in real time.

Yes. For global volume/sfx that you will adjust in option screen, the current best practice in Unity 5 is using the Audio Mixer. You can route Introloop’s audio to your mixer by following this tutorial : http://www.exceed7.com/introloop/getting-started.html

After this, the level of that track you routed to can be controlled from script. Mainly via SetFloat/GetFloat which you can then link to your slider UI.
https://unity3d.com/learn/tutorials/modules/beginner/5-pre-order-beta/exposed-audiomixer-parameters

1 Like

Thank you! I totally forgot about the new Audio features in Unity5. This mean I have to rewrite how I handle audio in the game again but it should be much easier to deal with.

1 Like

The only flaw I have seen with this, is for systems like the N3DS.
Ultimately, this solution is exactly what I need, but I cannot guarantee it will work for specific devices, which is why I am holding off on a purchase.
How would using your solution work for all devices, and not just a specific set for normal everyday user devices?

Hello, thank you for interested in Introloop. It’s true that I could not confirm either that if it is working on 3DS or not because I don’t have their dev kits. At first I assume it is Unity’s job to make the code cross-compile successfully but then there is the case like WebGL where all audio “Schedule” functions are still not implemented. (they told me it is ready in 5.4, but haven’t tested since then.)

I am not sure that it also happen in 3DS or not but I could not verify it. (I will update the website with a list of untested systems along with the next update)

Is the track decoded or is it streamed form the source?

Hello, sorry for the late reply. You can choose whatever import settings you like and they will be in effect like it normally did. (Encoding quality, playback mode, etc.)

Introloop uses original audio without cutting or altering anything. Internally basically it is 4 audio sources which cooperate with each others and each one have your music file loaded, so in turn, audio sources will respect all import settings.

IntroloopPlayer randomly doesn’t play the music at all (Unity 5.5). I don’t know how to reproduce it as it seems random.

In case you need it, the settings for the audioclip is:
Load in background disabled
Decompress On Load
Preload Audio Data enabled
Vorbis

Any ideas? Has anyone else experienced this?

Thank you for the report. I will look into this immediately.
My active project that also uses Introloop is also on 5.5, so I will try to reproduce it. (If I have fixed the issue, I will come back to report again.)

If the audio file is not sensitive, you can send the audio file, the audio’s .meta file, and the corresponding Introloop asset file (that contains the 2 loop points) to me via DM. It will help me find the problem!

I am pleased to inform you that version 2.0 of Introloop has finally been released. (It is also on sale 30% as a part of Unity open sale until the end of this April 2017.)

Release Note

  • (14/04/2017) Version 2.0 - New functions includes :

  • Pitch - You can now specify pitch in an IntroloopAudio asset file. If you would like to use multiple pitches of the same audio, you can just copy the asset file and have different pitches. It can reference to the same actual audio file. Works fine with pause, resume, automatic memory management.

  • Preload - A feature where critical precision of starting an Introloop Audio is needed. Load the audio by calling IntroloopAudio.Instance.Preload(yourIntroloopAudio) beforehand to pre-consume memory, and then call Play as usual afterwards.

  • Ogg Streaming as Introloop on iOS/Android - In Unity 5.5.2 they added support for choosing “Streaming” with OGG on iOS/Android. I am happy to inform that this option works with Introloop. Everthing will be the same except it will not cost you as much memory of an entire audio on Play as before in an exchange for some CPU workload.

The website (Introloop - Unity Plugins by Exceed7 Experiments) also has already been updated with demo of version 2.0, which you can try the song with altered pitch. As always, if you found any problems I am ready to help you here or in the e-mail. Thank you!

Hi,

That looks great ! i’m trying to achieve that but couldn’t get my head around how dspTime and playSchedule functions works.
Is it possible to loop the intro and the outro instead of looping the middle part ?

Hello. By definition of intro and outro I think it should not be seamlessly loopable? That’s why we need Introloop, to loop the middle loopable part, and you would not have an outro since by definition of “loop” the music should never ends, thus no need for an outro.

But if you do want to loop the intro over and over, you could set up the intro boundary as 0 and outro boundary as the “supposed to be” intro boundary.

With the same idea you could set the intro boundary as the “supposed to be” looping boundary and outro boundary as the song’s length, it should loop the outro over and over once it arrives there.

Please do clarify if I misunderstand something. Thank you.

I actually would like to loop the intro until a certain event, then play the middle part once and then play the “outro” over and over until another event ends the music (fade out).

EDIT: Nevermind, I actually managed to do what I wanted :slight_smile:

1 Like

The ONLY reason I bought this already is because I am making my game for other systems than this specific embedded one. It seems one could achieve the same effect by fully grasping dspTime, SetScheduledStartTime, SetScheduledEndTime, and PlayScheduled, but be it lack of time, laziness, or both, I just decided to use your tool as it will save me time in the end.
This all being said, I really need to know what kind of memory footprint I will have to expect compared to toher means of looping music. I actually have 2 other usable options available that approach this solution in a less than ideal manor without much memory overhead.
Can you please share in both Megabytes and Megabits (MB and MiB receptively) the typical memory overhead for a 3.5MB song at 32 bit Wav (on import)?
I am targeting the Nintendo 3DS, which already has limited memory, and I am trying to land it onto an Old 3DS variant which is even more crippled memory wise( try ~16MB memory to work with).
If you cannot specify something this precise, can you at least explain how much additional memory overhead it would have in general compared to a solution like 5000 samples of silence for a buffer, as my other method uses?

Hello. Yes this project is basically manipulating dspTime, SetScheduledStartTime, SetScheduledEndTime, and PlayScheduled to achieve the effect while multiple AudioSources coordinate with each other.

The memory overhead will be the same as Unity’s normal audio loading and playing, as it is basically just 4 AudioSources that loads the same audio. This means the memory depends on your import settings of the said audio. (Thus “Streaming” would use the least memory as it loads just around the playhead.) You can determine the memory overhead by dragging your 3.5MB 32-bit song to the AudioSource (with your desired loading type) and look at the Profiler. (Beware that just clicking the file might cause a false memory overhead as the Profiler profiles memories used for previewing in the editor)

Other than that, the additional memory overhead is from storing the GameObjects and variables that manages the looping mechanism. I don’t think that is significant compared to the audio data itself.

However Introloop does something more that are different from just issuing .Play() .Stop() directly to the AudioSource :

  1. When you stop the audio (and the audio finished fading out completely, if you choose to stop with a fade out), it is automatically unloaded from memory. This is not the case when you just call “Stop” to the AudioSource. This is in effect if you choose “Decompress on load” or “Compressed in memory” type.

  2. If you cross fade the audio, there will be a moment when both audio are in memory. This means if both audio file has “Decompress On Load” you will have the whole size of 2 audios in the memory in that cross fading moment. However, when it finished cross fading the faded out ones will be automatically unloaded. If your memory allowance is very critical you might want to avoid the cross fading by fading out the first song then begin playing the second song later.

Also please note that I haven’t test on the 3DS as I don’t have the dev kit. I once test on the WebGL build and there is a problem that web platform does not support any Scheduled methods at all, I don’t think that is the case with 3DS but there might be a similar problem of unsupported method that Unity team have not yet implement. In the case that it really does not work please inform me (and you can also issue a refund). Thank you.

1 Like

Please don’t get me wrong. I bought this for more platforms than the 3DS :wink:
I eventually plan to learn how dspTime, SetScheduledStartTime, SetScheduledEndTime, and PlayScheduled works for the sake of being thorough, but this tool is still quite useful.
This is why I said that the only reason I went ahead and bought it despite not being sure about 3DS support is I will definitely utilize it on other platforms. I am quite sure you have extensively tested it on PC and Android if nothing else, and as many users as you have, I am sure all Unity free platforms are tested, if not other systems that require devnet access (e.g. Playstation, Xbox, Nintendo, etc).
I have seen enough to be impressed. I can easily make a quick test as soon as possible to find out for you.

On another note, does this have pause and resume support? How does oneshot SFX sounds work?

Introloop can pause and resume! You can try the free demo in the website Introloop - Unity Plugins by Exceed7 Experiments the last 3 colored button can demonstrate the function.

The limitation is that if you issued Stop, currently there is no way to start at any other point besides the beginning. I planned to make it so that you can specify a time to start the song, that also take account of the looping function. (For example a song with 1s intro and 4s looping part, if you call PlayFrom(5) you would begin at the intro boundary because 5s means it have already looped 1 time.)

For oneshot SFX, Introloop is not designed to play SFX. You can instead use a normal PlayOneShot(). (I am not sure if I misunderstood something, as “SFX” is not supposed to be looping or has an intro?) Introloop is not a complete audio management as opposed solutions like Master Audio, SoundManagerPro etc. that aims to be all-in-one. Introloop is just a tool that you can use just for the BGM part of your game.