A simple tool and library for finding the offset of an audio file within another file.
The algorithm uses cross-correlation of standardised Mel-Frequency Cepstral Coefficients, so it should be relatively robust to noise (encoding, compression, etc). The accuracy is typically to within about 0.01s.
The tool outputs the calculated offset in seconds, and a "standard score" indicating the prominence of the chosen correlation peak. This can be used as a very rough estimate of the accuracy of the calculated offset - one with a score greater than ten is likely to be correct (at least for audio without similar repeated sections) within the accuracy of the tool; an offset with a score less than five is unlikely to be correct, and a manual check should be carried out. Note that the value of the score depends on the length of the audio analysed.
The tool uses FFmpeg for transcoding, so should work on all file formats supported by FFmpeg. It is tested for compatibility with Python 3.8-3.12 on Linux, Windows and macOS. Other Python versions and platforms may or may not work.
The aim of this open source project is to provide a simple tool and library that do one job well, and that can be the basis of customisation for more complex use cases. The forks of the base respository are worth exploring if you need a feature that is not included here. The maintainers welcome pull requests with bug fixes, new features and other improvements that fit this philosophy - please see CONTRIBUTING.md for details.
To install from source once downloaded from GitHub:
$ pip install .
Or, to install the latest package from PyPi.org:
$ pip install audio-offset-finder
If you are installing on macOS and use the third-party package manager HomeBrew, then you may wish to use pipx
instead of pip
.
You will need to install FFmpeg to use the command-line tool, or to use the file-related functions in the library.
To use the command-line tool:
$ audio-offset-finder --help
$ audio-offset-finder --find-offset-of file1.wav --within file2.wav
Offset: 12.26 (seconds)
Standard score: 28.99
$ audio-offset-finder --find-offset-of file2.wav --within file1.wav
Offset: -12.26 (seconds)
Standard score: 28.99
The following command-line options can be provided to alter the behaviour of the tool:
Option | Description |
---|---|
-h, --help | Show a help message and exit |
--find-offset-of audio file | Find the offset of this file... |
--within audio file | ...within this file |
--sr sample rate | Target sample rate in Hz during downsampling (default: 8000) |
--trim seconds | Only use the first n seconds of each audio file |
--resolution samples | Resolution (maximum accuracy) of search in samples (default: 128) |
--show-plot | Display a plot of the cross-correlation results |
--save-plot filename | Save a plot of the cross-correlation results to a file (in a format that matches the extension you provide - png, ps, pdf, svg) |
--json | Output in JSON for further processing |
You can fine-tune the results for your application by tweaking the sample rate, trim and resolution parameters:
To provide additional information about the accuracy of the result in addition to the standard score, the --show-plot
option shows a plot of the cross-correlation curve, and the --save-plot
option saves one to a file. The two options can be used separately, or together if you want to both view the plot and save a copy of it:
$ audio-offset-finder --find-offset-of file2.wav --within file1.wav --show-plot --save-plot example.png
A single well-defined peak such as the one shown in the image below is a good indication that the offset is correct.
To use the Python library:
from audio_offset_finder.audio_offset_finder import find_offset_between_files
results = find_offset_between_files(filepath1, filepath2, trim=30)
print("Offset: %s (seconds)" % str(results["time_offset"]))
print("Standard score: %s" % str(results["standard_score"]))
A find_offset_between_buffers()
function is also provided if you want to find offsets between audio buffers that you already
have in memory.
A number of automated unit tests are included (and run before any pull requests are accepted) to try and validate the basic functionality of the tool in different scenarios. You can run them yourself by simply installing pytest and running it in this repository's root folder:
$ pytest
If this tool doesn't meet your needs, there are others that you may wish to consider. For example:
The inclusion of a tool in this list does not constitute a recommendation regarding its use. You should carry out your own checks regarding performance, security, legality, appropriateness etc.
(c) 2014-2024 British Broadcasting Corporation and contributors
See the COPYING and AUTHORS files.
For details of how to contribute changes, see CONTRIBUTING.md.
The audio files used in the tests were downloaded from Wikimedia Commons: