Audalign: Audio Alignment and Recognition in Python

repository·main·Indexed 41 days ago

https://github.com/benfmiller/audalign

A Python package for processing and aligning audio files using audio fingerprinting, cross-correlation, and visual alignment. Version 1.3.1 provides tools to align multiple recordings of the same event, perform high-precision fine alignment via CorrelationRecognizer, and pre-process audio with noise reduction and uniform leveling. It includes utilities for calculating sound speed, ranking alignment confidence, and exporting shifted audio as separate or multi-channel files.

Tokens
4K
Snippets
20
Records
21
Agent score
100%

What's inside Audalign

  1. Install Audalign with optional dependencies

    main

    Audalign supports optional dependencies for specific features:

    • visrecognize: Enables the VisualRecognizer based on spectrogram image comparison.
    • noisereduce: Provides wrapper utilities for noise reduction.

    Use the following commands to install them:

    # For visual recognition
    pip install audalign[visrecognize]
    
    # For noise reduction
    pip install audalign[noisereduce]
    pip install audalign[visrecognize]
    pip install audalign[noisereduce]
  2. Set up ffmpeg or libav for Audalign

    main

    Audalign requires ffmpeg or libav to handle audio/video formats. Ensure one of these is installed and accessible in your system PATH.

    macOS (Homebrew)

    brew install ffmpeg --with-libvorbis --with-sdl2 --with-theora
    # OR
    brew install libav --with-libvorbis --with-sdl --with-theora

    Linux (apt)

    apt-get install ffmpeg libavcodec-extra
    # OR
    apt-get install libav-tools libavcodec-extra

    Windows

    1. Download and extract ffmpeg or libav binaries.
    2. Add the /bin folder to your PATH environment variable.
  3. Pre-process audio with `uniform_level_file()` and `remove_noise_file()`

    main

    To improve alignment accuracy, you can pre-process audio files. A common workflow is to level the volume and then remove noise.

    Uniform Leveling

    uniform_level_file(file_path, destination, mode='normalize'|'average', ...) levels the file by peak or average volume. This helps bring sound events up in volume to influence alignments.

    Noise Removal

    remove_noise_file(filepath, noise_start, noise_end, destination, ...) removes noise by specifying a start and end time of a representative noise section.

    import audalign
    
    # Workflow: Level -> Remove Noise -> Align
    audalign.uniform_level_file('input.wav', 'leveled.wav')
    audalign.remove_noise_file('leveled.wav', 1.0, 2.0, 'clean.wav')
    # Then use 'clean.wav' for recognition/alignment
  4. Align multiple files using `align()`

    main

    The align() function finds matches and relative offsets for all files within a directory_path, aligns them, and writes the results to a destination_path.

    Key arguments:

    • directory_path (str): Directory containing files to align.
    • destination_path (str): Path to write alignments to.
    • write_extension (str): Optional extension (e.g., ".wav") for output files.
    • write_multi_channel (bool): If True, writes a single combined file where each input is one channel. If False, writes individual shifted files and a combined file.
    • recognizer (BaseRecognizer): The recognizer to use (defaults to FingerprintRecognizer).
    • write_files_unprocessed (bool): If True, writes files without processing (e.g., doesn't normalize).
    import audalign
    
    # Align all files in a directory
    results = audalign.align(
        directory_path='path/to/audio_dir',
        destination_path='path/to/output_dir',
        write_extension='.wav',
        write_multi_channel=True
    )
  5. Remove noise from an audio file

    main

    The noise_remove function uses the noisereduce library to reduce noise in a file. It requires a noise profile, which can be extracted from a specific segment of the same file or an alternative file.

    Note: This function requires the noisereduce dependency. If missing, it will raise an ImportError stating skimage not found, please install 'visrecognize' module.

    from audalign.filehandler import noise_remove
    
    noise_remove(
        filepath="noisy_audio.wav",
        noise_start=0.0,      # Start of noise in seconds
        noise_end=2.0,        # End of noise in seconds
        destination="clean_audio.wav",
        prop_decrease=1.0    # Amount of noise reduction
    )
  6. Calculate sound speed with speed_of_sound()

    main

    Calculate the speed of sound in meters per second based on the temperature in degrees Celsius.

    Parameters:

    • degrees (int): Temperature in Celsius.

    Returns:

    • int: The calculated speed of sound.
    from audalign.datalign import speed_of_sound
    
    speed = speed_of_sound(20)
    # Returns speed at 20 degrees Celsius
  7. Shift and write aligned audio files

    main

    The shift_write_files function takes a dictionary of calculated shifts (where keys are file names and values are float offsets) and writes the files to a destination, applying the shifts by prepending silence.

    It can output:

    • Separate files: Each file is shifted individually.
    • Multi-channel total: A single file where each input audio file is assigned to a different channel (if write_multi_channel=True).
    • Total combined: A single file that overlays all shifted tracks (if write_multi_channel=False).
    from audalign.filehandler import shift_write_files
    
    # files_shifts: { 'file1.wav': 0.5, 'file2.wav': 1.2 }
    # names_and_paths: { 'file1.wav': '/abs/path/file1.wav', ... }
    
    shift_write_files(
        files_shifts=my_shifts,
        destination_path="/output/dir",
        names_and_paths=my_paths,
        write_extension=".wav",
        write_multi_channel=True
    )
  8. Find audio files in a directory

    main

    Use find_files to recursively yield all files within a directory that match specific extensions. It returns a tuple containing the full file path and the file extension.

    for file_path, extension in find_files("/path/to/audio", extensions=["wav", "mp3"]):
        print(f"Found {extension} at {file_path}")
  9. Apply alignment shifts to original files using `write_shifts_from_results()`

    main

    If you have processed files (e.g., files that were noise-reduced or leveled) to achieve better alignment, use write_shifts_from_results() to apply those calculated shifts back to the original source files.

    Arguments:

    • results (dict): The alignment results dictionary.
    • destination_path (str): Where to write the shifted files.
    • read_from_dir (str/list/None): The directory or list of paths containing the original files you want to shift. If None, it uses the files listed in the results object.
    • write_multi_channel (bool): Whether to write a combined multi-channel file.
    import audalign
    
    # Apply shifts found from processed files back to the original files
    audalign.write_shifts_from_results(
        results=results,
        destination_path='path/to/original_files_shifted',
        read_from_dir='path/to/original_unprocessed_files'
    )
  10. Create an AudioSegment with bounds and silencing

    main

    The create_audiosegment function loads an audio file and allows for precise segmenting. It can prepend or append silence based on the start_end parameter (provided as a tuple of seconds).

    Key features:

    • Bounds Checking: Automatically handles start/end points that exceed file length.
    • Silencing: If start_end is provided, it uses pydub.AudioSegment.silent to pad the start or end of the segment.
    • Preprocessing: By default, it sets the frame rate, sample width (2), and channels (1). If unprocessed=True, these conversions are skipped.
    • Normalization: If normalize=True, it applies pydub.effects.normalize.
    from audalign.filehandler import create_audiosegment
    
    # Create a segment from 10.0s to 20.0s
    segment = create_audiosegment(
        "audio.wav", 
        start_end=(10.0, 20.0), 
        sample_rate=44100,
        normalize=True
    )
  11. Remove noise from a directory of files

    main

    The noise_remove_directory function applies noise reduction to all audio files found in a directory. It supports multiprocessing to speed up the process.

    from audalign.filehandler import noise_remove_directory
    
    noise_remove_directory(
        directory="/path/to/noisy_files",
        noise_filepath="noise_profile.wav",
        noise_start=0.0,
        noise_end=1.0,
        destination_directory="/path/to/clean_files",
        use_multiprocessing=True,
        num_processes=4
    )