Look at this Time Samples documentation for play back, now if I could loop part of a wav file I could make an entire music track and then using Time.Samples go to the next play position and then loop that part, can it be done? please advise, thanks
The problem is not starting the audio at a precise position in the clip, but looping at an end position earlier than the clip’s end.
4 paths lie ahead:
The cunning
If you know your loop points in advance, instead of 1 big track import many chunks and loop these. Do NOT use Play but PlayDelayed and AudioSettings.dspTime, alternating AudioSources, to stitch clips sample accurately.
The lazy
Use AudioClip.Create to create empty clips of the appropriate size, and AudioClip.GetData and SetData to copy chunks of data to your runtime generated clips, which will loop perfectly. Wasteful, triggers a lot of garbage collection, but a usable strategy in some cases. Note that your source clip will have to be loaded in memory, not streamed.
The masochist
Read audio files yourself into audio data containers that you can pipe into OnAudioFilterRead().
The rich
Get G-Audio( see my signature ). It does what solution 3 suggests out of the box.
I’m intending to manipulate my own music into chunks so I’ll know the bpm/tempo before hand and hopefully using AudioSettings.dspTime and some cunning scripting I’ll try and follow Gregzo’s thinking with his option one perhaps, I’ll have individual sample files/wavs each one the exact same bpm and length only just adding instruments etc as you go on… so perhaps just playing my wavs one after the other just looping the current sound.
Fabric can read markers from wavfiles and set a loop region that can play indefinitely or for a number of times before it reaches the end… its doing this by creating audio sources for each section during initialization and then using the PlayScheduled and AudioSettings.dspTime to stitch them together sample accurately. Its not that wasteful because it doesn’t copy the data around (only once during awake) but it does mean that you cant change the loop region at runtime and that your audio clip has to be uncompressed and loaded into memory. However, it should be relative easy to support compressed and streamed audio clips simply by creating them automatically before you build the game for the target platform.
In case anyone’s wondering what Fabric is, that’s because it’s not on the Asset Store. Tazman has his own website dedicated to it. A quite advanced product for sure. Not sure if there’s a reviews section though?
More information that I don’t think anyone offered. When you play an mp3 for sound effects, there’s an extremely long latency and slowdown before it starts playing. That is not true of wav files (start playing 120x faster). So stay far away from mp3’s for sound effects at all costs.
Hi, I wrote this simple code to loop on a part of the audio :
public AudioSource myAudio;
[Range(0f, 3.5f)] // 2nd value should be the duration of the audio in seconds
public float loopStart, loopEnd;
void Start(){
myAudio.Play();
}
void Update(){
if (myAudio.isPlaying && myAudio.time > loopEnd) {
myAudio.time = loopStart;
}
}
That code will not work perfectly. The update code only runs once per frame. Three problems with this. Number one is that you’re only going to get probably 30 to 60 frames per second when this code will run. Number two is that your frames are all not probably exactly the same length between each other all the time. Number three is the frame and your code will not happen at exactly the moment you want, hence your greater than sign. If you could do it with an equal sign and not greater than , it would theoretically work, but it’s impossible if the code only runs once a frame. You could over shoot your target ending by a lot and actually it probably will loop at a different point every single time.
I wish that code would work. It would make things so easy.
Bad news
It was quite to simple to work, wasn’t it ?
You’re probably right, although it seems to work for me (but with a poor quality result, maybe because my audio wasn’t designed for looping).
Well, a better solution is still to be found.