How can I loop a section of a sound?

KX_SoundActuator.time, easily enough.

This one is cursed, however. Setting it to zero may set it to -48k instead and crash your sound drivers by some miracle of shoddy engineering. Trying to loop backwards will be weird, trying to be smart and mess with the playback speed this way will also not work as you might expect.

First issue: never going to be fixed. For the second one there might be a way, and as for the third one to change playback speed you want to look at pitch instead.

Here is a barebones example:

from bge.logic import getCurrentController;
cont=getCurrentController();
own=cont.owner;

sound=cont.actuators["Sound"];
if("nit" not in own):
    sound.startSound();
    own["nit"]=1;

def loop(x, start, end):
    if(x.time>end):
        x.time=start;
    
    elif(x.time<start):
        x.time=start;

loop(sound, 0.01, 3.25);

And here’s calling that script with them blocks.

As a final note, notice the delay sensor is only checking every 16 frames or so, you might think that’s too slow of an update but it might as well be overkill. Since the value is in seconds you only need to check however many fractions of a second (in logic frames) you’re interested in slicing.

ADDENDUM (07/03/23):

Activation of the sound actuator through a controller pulse is required for 3D sound to take the camera into account; the original script does not handle this.

Adding cont.activate(sound) or it’s brick equivalent always->and->sound ensures that the camera update is run, fixing the issue.