Looping a sound: Difference between revisions
m (→Wavosaur: Reworded the warning about Source to make it more explicit.) |
(→With a hex editor: Added code for a BAT file to loop a wav via drag-n-drop.) |
||
Line 69: | Line 69: | ||
=== With a hex editor === | === With a hex editor === | ||
Appending the following bytes to the end of a non-looping [[WAV]] file will make it loop in its entirety: | Appending the following bytes to the end of a non-looping [[WAV]] file will make it loop in its entirety. These bytes represent a cue chunk that defines a cue point at the very first sample: | ||
<pre><nowiki>63 75 65 20 1C 00 00 00 01 00 00 00 01 00 00 00 00 00 00 00 64 61 74 61 00 00 00 00 00 00 00 00 00 00 00 00</nowiki></pre> | <pre><nowiki>63 75 65 20 1C 00 00 00 01 00 00 00 01 00 00 00 00 00 00 00 64 61 74 61 00 00 00 00 00 00 00 00 00 00 00 00</nowiki></pre> | ||
The bash shell script used to generate | {{tip|If using {{linux}} or {{macos}}, put the above into a file named <code>cue.bin</code>, then run <code>cat my_nonlooping_sound.wav cue.bin > my_looping_sound.wav</code>. | ||
The bash shell script used to generate <code>cue.bin</code> is provided below, based upon [https://www.recordingblogs.com/wiki/cue-chunk-of-a-wave-file documentation from recordingblogs.com]. | |||
{{expand|title=cue.sh|1=<source lang=sh>#!/bin/bash | {{expand|title=cue.sh|1=<source lang=sh>#!/bin/bash | ||
Line 120: | Line 121: | ||
rm -f cue.bin | rm -f cue.bin | ||
append_cue cue.bin</source>}} | append_cue cue.bin</source>}} | ||
}} | |||
The following is a batch script file for {{windows|4}} that appends the above bytes to the input files. Create a text file, paste the text in and save the file with the <code>.bat</code> extension. Drag-dropping non-looping WAV files on it (i. e. running the script with <code>%1, %2, ...</code> being the input files) will create looping copys ending with <code>_loop.wav</code>. | |||
{{Expand|title=loop_wav.bat| | |||
<syntaxhighlight lang=batch> | |||
@echo off | |||
setlocal | |||
rem Message for empty input | |||
if "%~1"=="" ( | |||
echo Please drag and drop one or multiple non-looping WAV files onto this script. | |||
echo For each file it will create a new copy ending with "_loop.wav" which will loop in Source games. | |||
pause | |||
exit /b | |||
) | |||
rem Define the names of helper files that we will need | |||
set "chunkTxt=temp_cue_chunk.txt" | |||
set "chunkBin=temp_cue_chunk.bin" | |||
rem Create a temporary text file containing the cue chunk as hex values | |||
>"%chunkTxt%" ( echo:63 75 65 20 1C 00 00 00 01 00 00 00 01 00 00 00 00 00 00 00 64 61 74 61 00 00 00 00 00 00 00 00 00 00 00 00 ) | |||
rem Convert the hex values to a binary file - that's what we will append to the WAV files | |||
rem The certutil.exe lives in Windows/System32/ and should exist since XP | |||
certutil -f -decodehex "%chunkTxt%" "%chunkBin%" >nul | |||
rem Append the cue chunk to the WAV file | |||
for %%F in (%*) do ( | |||
copy /b "%%~F"+"%chunkBin%" "%%~dpnF_loop.wav" >nul | |||
echo Created looped WAV file "%%~nF_loop.wav". | |||
) | |||
rem Delete helper files | |||
del "%chunkTxt%" | |||
del "%chunkBin%" | |||
pause | |||
</syntaxhighlight> | |||
}} | |||
== Cue location == | == Cue location == |
Revision as of 16:17, 10 January 2025
A looped sound will repeat endlessly without any gap between its end and start. It is up to the sound artist to ensure that the end and start of the file match up however, or there will be a "pop" as the waveform jumps from one shape to another.
GoldSrc and
Source detect looped sounds ONLY through cue points embedded in the file. This is a WAV-only feature, so MP3s cannot be looped. Microsoft ADPCM compressed WAVs can be looped, but due to the way they are encoded, there may a pop when the sound restarts if the sound is shorter than a few seconds.








Looping a WAV
These free programs can add cue points to a WAV:
- GoldWave (trialware)
- Wavosaur (freeware)
- LoopAuditioneer (free and open source)
- OcenAudio (freeware)
GoldWave
Open Goldwave and open the sound you want to loop. Click the cues icon. ()
Then in the new window click on the New button and add a cue point At Start. Then click New for another cue point and add a point At End. So it looks similar to this:
Wavosaur






Looping from beginning to end
- Open Wavosaur.
- Open the sound you want to loop.
- Go to
Tools > Markers > Create marker
, or press M. This will add a new M0 marker at the beginning.- If the marker is not at the beginning, move it there by dragging it with the mouse.
After that, click "Save" or "Save As".
Looping from anywhere in the file
- Open Wavosaur.
- Open the sound you want to loop.
- Go to
Tools > Loop > Create loop points
. It should create loop points.- You can change their positions by dragging them.
- If you're looping a sound for Source, the end point should be moved at the end of the track, as end cues are not functional (see the Discussion page). You should trim the end instead.
- Double-clicking between the loop points will select the whole region between them and allow you to play it on loop.
Once you have found a satisfying position for the starting point:
- Click outside of the selection to clear it.
- Double-click the area between the loop points to select it.
- Do NOT play it now! Wavosaur uses the "playing position" to create markers.
- Go to
Tools > Markers > Create marker
, or press M. This will add a new M0 marker at the exact position of the loop's starting point. - Go to
Tools > Loop > Delete loop points
to clean up the unnecessary data. Failure to do so is inconsequential in Source, but will result in the track not looping in GoldSrc.
After that, click "Save" or "Save As".

With a hex editor
Appending the following bytes to the end of a non-looping WAV file will make it loop in its entirety. These bytes represent a cue chunk that defines a cue point at the very first sample:
63 75 65 20 1C 00 00 00 01 00 00 00 01 00 00 00 00 00 00 00 64 61 74 61 00 00 00 00 00 00 00 00 00 00 00 00



cue.bin
, then run cat my_nonlooping_sound.wav cue.bin > my_looping_sound.wav
.
The bash shell script used to generate cue.bin
is provided below, based upon documentation from recordingblogs.com.
#!/bin/bash
# Wave file cue chunk according to https://www.recordingblogs.com/wiki/cue-chunk-of-a-wave-file
# Original script by SavageX; permission is granted to modify as needed.
ECHO="echo -en"
OUT="cue.bin"
function append_bytes() {
$ECHO $1 >> $OUT
}
function append_cue() {
OUT=$1
# chunk ID, "cue "
append_bytes "cue\x20"
# size of the chunk: (12 + 24) - 8 = 28
# Why -8? ID and size don't count.
append_bytes "\x1C\x00\x00\x00"
# number of data points: 1
append_bytes "\x01\x00\x00\x00"
# ID of data point: 1
append_bytes "\x01\x00\x00\x00"
# position: If there is no playlist chunk, this is zero
append_bytes "\x00\x00\x00\x00"
# data chunk ID
append_bytes "data"
# chunk start: 0
append_bytes "\x00\x00\x00\x00"
# block start: 0
append_bytes "\x00\x00\x00\x00"
# sample start: 0
append_bytes "\x00\x00\x00\x00"
}
rm -f cue.bin
append_cue cue.bin
|
The following is a batch script file for Windows that appends the above bytes to the input files. Create a text file, paste the text in and save the file with the
.bat
extension. Drag-dropping non-looping WAV files on it (i. e. running the script with %1, %2, ...
being the input files) will create looping copys ending with _loop.wav
.
@echo off
setlocal
rem Message for empty input
if "%~1"=="" (
echo Please drag and drop one or multiple non-looping WAV files onto this script.
echo For each file it will create a new copy ending with "_loop.wav" which will loop in Source games.
pause
exit /b
)
rem Define the names of helper files that we will need
set "chunkTxt=temp_cue_chunk.txt"
set "chunkBin=temp_cue_chunk.bin"
rem Create a temporary text file containing the cue chunk as hex values
>"%chunkTxt%" ( echo:63 75 65 20 1C 00 00 00 01 00 00 00 01 00 00 00 00 00 00 00 64 61 74 61 00 00 00 00 00 00 00 00 00 00 00 00 )
rem Convert the hex values to a binary file - that's what we will append to the WAV files
rem The certutil.exe lives in Windows/System32/ and should exist since XP
certutil -f -decodehex "%chunkTxt%" "%chunkBin%" >nul
rem Append the cue chunk to the WAV file
for %%F in (%*) do (
copy /b "%%~F"+"%chunkBin%" "%%~dpnF_loop.wav" >nul
echo Created looped WAV file "%%~nF_loop.wav".
)
rem Delete helper files
del "%chunkTxt%"
del "%chunkBin%"
pause
|
Cue location
Your cues do not have to be at the start and end of the file. If you place them in the middle Source will start playing the sound normally, then when it reaches the end cue will loop back to the start cue. From then on only what's between the cues will play.



This bug doesn't impact loops that start at the beginning, as 0 divided by 2 is still 0. (tested in:

This can be used to give a sound a "winding up" effect that only plays once (e.g. a motor starting).
Looping an MP3
In Source, MP3 files can't be looped with start/end queues like a WAV. A logic_timer can be a good workaround; have it start playing the sound again after it has fully played (or has played to the point desired).
This could also be done using User I/O from the ambient_generic
to itself, and an input delay (another entity will still need to be used to trigger the initial input).


See also
External links
- Looping Menu Music - An Interlopers.net Tutorial on Soundlooping