Rebol3 Code Examplex
Audio overlap loop
Play overlapping audio segments in a continuous loop.
Rebol [
title: "Rosetta code: Audio overlap loop"
file: %Audio_overlap_loop.r3
url: https://rosettacode.org/wiki/Audio_overlap_loop
]
;; Import the MiniAudio extension for audio playback functionality
;; See: https://github.com/Oldes/Rebol-MiniAudio
audio: import miniaudio
;; Path to the audio file to be played
file: %drumloop.wav
;; How many overlapping instances of the sound to play
number-of-sounds: 8
;; Seconds between each sound's start time (creates a staggered/canon effect)
delay-between-sounds: 0.01
;; Download the sample audio file if it doesn't already exist locally
unless exists? file [
write file
read https://github.com/Oldes/Rebol-MiniAudio/raw/refs/heads/master/assets/drumloop.wav
]
;; Initialize the first available playback device.
;; IMPORTANT: The device handle must be kept in a variable — if it goes out of
;; scope, the garbage collector will release it and playback will stop.
device: audio/init-playback 1
;; Load the audio file and print basic info about what we're about to play
sound: audio/load :file
print ["Play" number-of-sounds "overlaping loops:" to-local-file/full file]
print ["Sound duration:" sound/duration]
;; Build a block to track all loaded sound instances for later cleanup.
;; Each sound is loaded separately so they can play simultaneously (overlapping).
;; It is safe to call `audio/load` with the same file multiple times — the
;; extension manages instances internally, so no manual deduplication is needed.
;; Sounds are staggered in time: each one starts after the previous finishes,
;; plus the small delay, creating a cascading/phasing canon effect.
sounds: [] start-time: 0:0:0
loop number-of-sounds [
append sounds sound: audio/load :file ;; load a fresh instance
audio/start/loop/at :sound :start-time ;; schedule it to start at staggered time
start-time: start-time + sound/duration + delay-between-sounds ;; advance offset
]
;; Wait long enough for all staggered sounds to finish playing
wait sound/duration + start-time
print "Start stoping sounds..."
;; Gracefully stop each sound one at a time, using a fade-out equal to
;; the sound's own duration, then waiting for that fade to complete
;; before moving on to the next one.
while [not empty? sounds][
sound: take sounds
audio/stop/fade sound sound/duration ;; fade out over one sound-duration
wait sound/duration ;; wait for the fade to finish
]
print "Done"
;; Release the playback device now that all sounds have stopped
release device