All notable changes to this project will be documented in this file.
The format is based on Keep a Changelog, and this project adheres to Semantic Versioning.
- Updated dependencies.
- The output of
--alt-export-top
wrapping in some edge cases (#43) - Active audio streams interrupted in some cases on Windows (#21)
- Updated dependencies.
- Minor internal changes for deprecated library functionalities/imports.
- BPM is now correctly derived from librosa 0.10.2's updated beat_track function.
- Added proper Python 3.12 support.
- Updated dependencies.
- Support for Python 3.8 has been removed. The minimum supported Python version for PyMusicLooper is now Python 3.9.
- New option in
export-points
:--fmt
, to customize the exported loop points format. Options:samples
(default),seconds
, ortime
(mm:ss.sss).
- Minor internal code clean-up and refactoring.
- Updated dependencies.
- Output directory is created only when needed for PyMusicLooper exports, instead of pre-emptively.
- The absolute path of the export file/directory is now always returned, even if the provided output directory is relative, for clarity.
- Import
taglib
only when required, isolatingtaglib
ImportErrors to the affected functions only, instead of blocking the use of the entire library.
- Fixed
pymusiclooper --version
reporting v3.1.0 instead of the actual package version; affects versions 3.2.0 and 3.2.1
- When successful, the
extend
command now displays the file path of the extended audio file to the user instead of the output directory
- Fixed initial loops' output from the
extend
command being affected by the fade out parameter - Fixed minutes/seconds rounding issues with the
extend
command file naming scheme
- New command:
extend
. Export a longer, extended version of an audio track by looping it seamlessly to the desired length. - Additional option in
export-points
:--alt-export-top N
. Can be used to return the N top loop points; provides the same output as in interactive mode but without the table formatting.--alt-export-top -1
to export all. - Added CLI_README.md for a basic CLI overview/reference
- Playback progress bar now updates faster for smoother transitions
- Skip beat analysis if
--brute-force
is enabled, for slightly faster runtime - Simplified many internal interfaces and added type hints and documentation to most core functions
- Lazy load yt_dlp and sounddevice so that they are only imported when needed
- Updated many core dependencies, including yt-dlp to their latest version
- Improve
--debug
option with better exception debug output - Lowered the minimum supported Python version to 3.8, since it is already compatible
- Enabled initial Python 3.12 support
- Fixed zero crossing algorithm offset potentially being out-of-bounds in very rare cases
- Playback progress bar showing current playback progress and time
- Candidate pruning now activates if there are 100 or more initial pairs, instead of 250 as in the previous version
- Loudness and note difference threshold incorrectly swapped in candidate pair pruning
-
New functionality:
tag
. Export metadata tags of loop points to a copy of the input audio file(s) - (Credit: some of the implementation code was based on/inspired by RemedyTwo's fork) -
New functionality:
play-tagged
. Reads the metadata tags of loop points from an audio file and plays it looping -
New audio source option:
--url
. Can now load and process audio from a youtube link (or any stream supported by yt-dlp) -
New loop point search options
--min-loop-duration
,--max-loop-duration
: added min loop duration and max loop duration (in seconds) as optional constraints to the CLI--approx-loop-position
: specify the approximate desired loop start and loop end in seconds, searching around those points only +/- 2 seconds--brute-force
: enables an alternative loop discovery mode that checks the entire audio track instead of the detected beats; useful in case the main algorithm does not yield the desired results.--disable-pruning
: disables the internal filtering of potential loop points
-
New export option for split-audio command:
--format
, to change the format of the exported split audio files (currently supported formats: WAV, FLAC, OGG, MP3) -
Official Python 3.10 and 3.11 support
- Complete re-write of the CLI with much better interface and usability, use
pymuisclooper --help
for the new commands and options or consult the README - Reimplemented playback using the python sounddevice library instead of mpg123 for better cross-platform compatibility
- Significant runtime improvement to the core loop search algorithm (now runs 10x faster).
- Better loop point alignment thanks to an internal implementation of Audacity's "At Zero Crossings" functionality (less cases of audio popping/clicking due to misaligned loop points)
- Much nicer formatting and interface in interactive mode thanks to the
rich
python package - Increased the minimum Python requirement to Python 64-bit >=3.9
- Multiprocessing option (
--n-jobs
). Batch mode operations are otherwise unaffected and work as if--n-jobs
was fixed to 1.
- Completely removed defunct preserve tags function and its associated errors
- Hotfix for v2.5.1's redundant mpg123-related error message
- Added workaround for libsndfile mp3 loading issue
- Fixed error handling when no loop points were found, when audio has not been loaded or when mpg123 is unavailable.
- Moved the --recursive, --flatten and --n-jobs into their own "Batch Options" CLI arguments category for clarity
- Added option to print loop points to terminal STDOUT (contributed by Coolsonickirby).
- Project relicensed to MIT license as of v2.5+.
- Temporarily disabled preserve_tags features to resolve dependency installation issues; pending re-implementation.
- Partial code re-organization and improvement; better exception handling
- Merged the 'complete' installation option with the 'core' installation
- CLI can now be launched directly by calling
pymusiclooper
in the terminal
V2.0 Rationale: This release marks a milestone in stability over the v1.x versions, rather than a major update. Future major releases will be reserved for large changes in the code base (e.g. overhaul of the core algorithm), or breaking changes in API/shell commands.
- Removed --json export option in favor of the more versatile--txt option
- Performance improvements to beat comparisons as a result of using native numpy functions whenever possible
- Code refactoring and streamlining of internal functions
- Added a --txt option to export a loop.txt file compatible with LoopingAudioConverter
- Recursive batch export now replicates the source directory tree structure by default to avoid name conflicts
- Added a --flatten option for recursive batch export to output to a single folder without replicating the source directory structure (previous behaviour)
- Lowered note similarity threshold to improve loop point quality (from 10% to 8%)
- Renamed default output directory name from looper_output to Loops
- Fixed JSON export bug
- Fixed a bug with non-recursive batch export.
- Added -i/--interactive feature to CLI for manual loop previewing and selection
- Fixed an issue with the loop ranking algorithm triggering with lists having < 2 candidates
- Batch command option removed
- Batch mode is now enabled automatically if the given path is a directory
- Major improvements to the core loop finding algorithm.
- Added option to preserve/transfer the track's original tags
- Fixed batch processing mode selection
- Added multiprocessing support and progress bar for batch export
- Save export output to a "looper_output" folder in current directory by default
- Removed unreliable cache implementation
- Added support for batch processing and specifying a different output directory
Initial Release: PyMusicLooper - a script for repeating music seamlessly and endlessly.
Features:
- Find loop points within any music file (if they exist)
- Supports most audio formats (MP3, OGG, M4A, FLAC, WAV, etc.)
- Export to intro/loop/outro sections for editing or seamless playback within any music player that supports gapless playback
- Export loop points in samples for use in creating custom themes with looping audio