Conditionally batch-convert audio samples into minimal .wav files
This script scans directories for audio samples and batch-converts them into
small .wav files, based on target criteria. This is useful to save storage
space and reduce the I/O stress during simultaneous real-time streaming
of multiple .wav files on devices like the Dirtywave M8 tracker.
If you have directories full of 24/32-bit stereo .wav files or stereo
samples with effectively mono content, this script can reclaim wasted storage
space and reduce I/O stress on your SD card. It can even detect if the content
of a stereo sample is actually mono & convert it for you!
bash sample-shrinker.sh [options] FILE|DIRECTORY ...Each DIRECTORY is recursively searched for audio files to process, based
on their extension (.wav by default, configure with -x). Any FILE
specified directly will be processed (regardless of its extension).
The basics:
- Samples are converted in place
- The original file is backed up under '_backup/' (change with
-d) - Backups generate spectrogram
.pngfiles to compare old & new files (disable with-S)
- The original file is backed up under '_backup/' (change with
- Only samples that DON'T meet the target criteria will ever be changed
- Samples are only converted to SMALLER target bit-depth (
-b) or channels (-c)- ...unless a minimum bit-depth is specified (
-B, disabled by default)
- ...unless a minimum bit-depth is specified (
- Stereo samples can be conditionally converted to mono using auto-mono (
-a)- the threshold for automatic conversion is configurable (
-A)
- the threshold for automatic conversion is configurable (
If a sample does not already meet the target BIT_DEPTH or CHANNELS, it will be
converted in place and the original will be backed up to a parallel directory
structure (default: _backup).
Upon conversion, spectrogram .png files are generated alongside the backed-up
original file, to compare the original vs new audio files (disable with -S)
You can review the characteristics of all sample files, and see if/why they
would be converted by running with -l. You can preview only samples that
would change with -n.
Run sample-shrinker.sh -h to see all the options.
bash sample-shrinker.sh directory_of_samples/This uses the default options, where:
- The target bit-depth is
16(change with-b BITRATE) - Stereo channels are always left unchanged (change with
-a,-A DB, or-c1) - The original files are backed up to a parallel directory structure under
_backup/(change location with-d) - Spectrogram
.pnggraphics that compare the old and new files are generated alongside the backed-up file (Use-vto pr
Unless you use -v to increase verbosity, the script will output one line per
sample, summarizing its properties and any changes it makes:
bash sample-shrinker.sh -a -A-80 inst/ vocals/
16 st->m+A -inf 16/16 inst/drums/anvil.wav [CHANGED]
16 st->m+A -84.29 16/16 inst/drums/kalimba.wav [CHANGED]
16 st -60.21 16/16 inst/drums/closed_hh.wav
8 mono 8/8 inst/waves/triangle.wav
16 mono 16/16 inst/waves/monowave.wav
24->16 mono 23/24 vocals/otr-snippet.wav [CHANGED]
32->16 st -22.48 31/32 vocals/accapella.wav [CHANGED]
- Changed files are followed by
[CHANGED] - Specific changes are denoted with
->- If the change has additional was automatically decided, it will be followed
with
+and a character to describe the reason:+A: decided by auto-mono (-a/-A)+P: pre-normalize before down-converting bit-depth (-p)+M: auto-converted to meet the minimum bit-depth (-B, unset by default)
- If the change has additional was automatically decided, it will be followed
with
- The columns are: bit depth, stereo, stereo diff, effective bit-depth, file path
Use -l to scan and list each sample, and summarize what would be changed
based on the other options:
bash sample-shrinker.sh -l -a -A-80 inst/ vocals/
16 st->m+A -inf 16/16 inst/drums/anvil.wav [CHANGE]
16 st->m+A -84.29 16/16 inst/drums/kalimba.wav [CHANGE]
16 st -60.21 16/16 inst/drums/closed_hh.wav
8 mono 8/8 inst/waves/triangle.wav
16 mono 16/16 inst/waves/monowave.wav
24->16 mono 23/24 vocals/otr-snippet.wav [CHANGE]
32->16 st -22.48 31/32 vocals/accapella.wav [CHANGE]
The output will look identical to conversion, but it will not alter any files
This detects stereo samples that are effectively mono and converts them to mono:
bash sample-shrinker.sh -a dir1/ dir2/Stereo content is "effectively mono" if―after summing its first two channels after inverting one of them—the resulting Peak dB level is below -95.5 dB.
To configure the auto-mono threshold to be -80 dB:
# Note: `-A` implies `-a`
bash sample-shrinker.sh -A -80 dir1/ dir2/bash sample-shrinker.sh -p dir1 dir2Pre-normalizing before downsampling will preserve as much dynamic range as possible, but it is disabled by default: if the sample is part of a level-balanced collection (like a single hit from a drum kit), normalizing the sample would change its relative volume with the rest of the collection.
bash sample-shrinker.sh -d - .Specifying - as the backup directory will disable backups. As a side effect,
This also disables the before/after spectrograph images (because they are saved
under the backups' directory tree).
- Bash
- Tested with Bash 5.1.16
- Requires at least Bash 5
- NOTE Mac/OSX users will need to
homebrew install bash, because the default terminal bash is stuck at 3.2(!)
- NOTE Mac/OSX users will need to
- SoX
- Tested with 14.4.2
- Requires sox >= 14.3 to support automatic
--no-ditherfor 8-bit samples