Python script for converting audio files to 16 bit, 48k - s2400converter.py

Here’s a Python script that processes audio files and converts them to 16-bit, 48kHz WAV files for native use with the S2400 sampler.

This script will preserve the directory structure. It will only process .wav, .aif, and .aiff files, ignoring all others. The only file name changes are that it replaces spaces in file names with underscores.

I tried it with files in all kinds of different sample rates and different bit rates, such as EPROM dumps from various drum machines, stereo, mono, it worked fine for all of them.

Usage: Detailed instructions in the comment. In summary, put all the audio file containing dirs you want to convert into the source dir, and give it the output path. Then run the script with the command line params. If you run the script without parameters, it will output help.

PS- it’s unsupported and I’m not responsible for any damage caused by running this script. If you have a file that doesn’t process and want to debug, there are lines commented out that will output information about what the script is doing. Also, setting “-V1” to “-V4” will give MUCH more verbose output. Most likely any change will be to the sox params in the command = list.

Edit - I made a small change since posting (1.1) that breaks the conversion into two steps which allows me to use the best conversion settings sox offers.

s2400converter.py

import os
import shutil
import subprocess
import sys

def print_usage():
    """Print the usage instructions for the script."""
    print("""
    s2400converter.py version 1.1

    This script recursively processes a directory of audio files and converts them to 16-bit, 48kHz WAV files for use with the S2400 sampler.

    The script will preserve the directory structure and will replace spaces in file names with underscores.

    How to Use:

    1. Place the script in a directory.
    2. Open a terminal or command prompt.
    3. Run the script with the following command:
       
       python3 s2400converter.py <source_dir> <dest_dir>
       
       - <source_dir>: The path to the source directory containing your audio files (e.g., /path/to/source).
       - <dest_dir>: The path to the destination directory where the converted files will be saved (e.g., /path/to/destination).

       Example:
       
       python3 s2400converter.py /path/to/source /path/to/destination

    4. The script will process all audio files in the source directory (WAV, AIFF, AIF formats) and convert them to 16-bit 48kHz WAV files, saving them in the destination directory.
       - Any file with spaces in its name will have spaces replaced with underscores.
       - Non-audio files will be skipped.

    Requirements:
    - Python 3.x
    - SoX (Sound eXchange) installed on the system for audio file conversion. To install SoX:
      - On macOS: brew install sox
      - On Linux: sudo apt-get install sox
      - On Windows: Download from http://sox.sourceforge.net/

    Note: Make sure the source and destination directories are valid and accessible.

    - by MSTRBLSTR
    https://www.instagram.com/mstrblstr_music/
    """)

def convert_audio(src_file, dest_file):
    temp_file = "temp.wav"
    # Step 1: Normalize to -0.5 dBFS
    norm_command = [
        'sox', '-V1', '-G', src_file, temp_file,
        'norm', '-0.5'
    ]
    subprocess.run(norm_command, check=True)
    
    # Step 2: Resample 
    resample_command = [
        'sox', '-V1', '-G', temp_file,
        '-r', '48000', '-b', '16', dest_file,
        'rate', '-v', '-M'
    ]

    subprocess.run(resample_command, check=True)

    # Clean up temp file
    os.remove(temp_file)

def process_directory(src_dir, dest_dir):
    """Recursively process the source directory, maintaining structure and converting audio files."""
    for root, _, files in os.walk(src_dir):
        rel_path = os.path.relpath(root, src_dir)
        new_dir = os.path.join(dest_dir, rel_path)
        os.makedirs(new_dir, exist_ok=True)

        for file in files:
            src_file = os.path.join(root, file)
            new_filename = file.replace(" ", "_")  # Replace spaces with underscores
            dest_file = os.path.join(new_dir, new_filename)

            if file.lower().endswith((".wav", ".aif", ".aiff")):
                convert_audio(src_file, dest_file)
            # else:
                # print(f"Skipping non-audio file: {src_file}")

if __name__ == "__main__":
    if len(sys.argv) != 3:
        print_usage()
        sys.exit(1)

    source_dir = sys.argv[1]
    dest_dir = sys.argv[2]

    if not os.path.isdir(source_dir):
        print(f"Error: Source directory '{source_dir}' does not exist.")
        print_usage()
        sys.exit(1)

    process_directory(source_dir, dest_dir)
    print("Conversion complete.")

3 Likes

I’m new to the S2400, can you explain why this is necessary? I have been importing and using 24/44.1 without issue. Will it not work with the FX or something?

44.1 samples are supported but they have to be resampled to 48 during playback. According to the manual this can lead to more aliasing in the lower frequencies.

Also using higher than 16 bit samples is more taxing on the CPU.

2 Likes

aliasing actually happens at higher frequencies :wink:

1 Like

So I’m fine with 44.1 just that my 24 bit samples are more taxing on the CPU?

Well I found an error in the manual for you guys then. :grin:

Aliasing artefacts become more noticeable as the pitch of the sample is lowered. Perhaps that is what they were trying to get at.

2 Likes

I made a small change to how sox is called to make better use of its highest quality and punchiest conversion modes.

2 Likes

:man_shrugging: maybe, but it definitely needs a rewrite if that’s what they intended to say.

1 Like

who reads manuals anyway :stuck_out_tongue:

4 Likes

:raised_hand::nerd_face:

3 Likes

Why the LLMs, of course !

3 Likes

Manual updated in dev.

4 Likes

This is a cool thread you guys!
The way I’ve been doing it is in the terminal with ffmpeg. First, you have to install ffmpeg with the command line, then navigate to the directory you want to convert, then type/paste the following:

(sample rate convert all wav 48k16b (for S2400)

mkdir convert48 ; find . -name “.” -exec ffmpeg -i {} -acodec pcm_s16le -ar 48000 convert48/{}_48k16b.wav ;

This one makes a new directory and throws them in there.

I’m definitely going to try the python one since I do a lot of this stuff for my Octatrack and 2400 etc

Thanks!
Rithers