audio_helper.main module

Audio Helper — implementation module.

Utilities for working with audio files: format conversion, duration probing, load/save in numpy form, regular-interval splitting, concatenation, room-tone mixing, silent-segment generation, and optional Demucs-based source separation.

Dependencies

  • ffmpeg-python (wraps the system ffmpeg binary)

  • numpy

  • soundfile

  • scipy

  • tqdm

  • os-helper

Optional (demucs extra)

  • torch, torchaudio — only required by separate_sources() and loaded lazily via _require_torch() / _require_torchaudio(). Install with: pip install 'audio-helper[demucs]'.

Usage Example

>>> import audio_helper as ah
>>> ah.sound_converter("in.mp3", "out.wav", freq=44100, channels=1)
>>> duration = ah.get_audio_duration("in.mp3")
>>> ah.mix_room_tone("narration.wav", "narration-rt.wav", noise_db=-42)

Author

Warith Harchaoui, Ph.D. — https://linkedin.com/in/warith-harchaoui/

audio_helper.main.audio_concatenation(audio_files, output_audio_filename=None, overwrite=False)[source]

Concatenate multiple audio files into a single audio file.

Parameters:
  • audio_files (list) – List of paths to the audio files.

  • output_audio_filename (str or None, optional) – Path to save the concatenated audio file. If None, the output file will be saved in the same folder as the first audio file.

  • overwrite (bool, optional) – Whether to overwrite the output file if it already exists (default is False).

Returns:

Path to the concatenated audio file

Return type:

str

Notes

The function uses ffmpeg to concatenate multiple audio files into a single audio file.

audio_helper.main.extract_audio_chunk(audio_file, start_time, end_time, output_audio_filename=None, overwrite=True)[source]

Extract a chunk of audio from an audio file between specified start and end times.

Parameters:
  • audio_file (str) – Path to the input audio file.

  • start_time (float) – Start time in seconds for the chunk to extract.

  • end_time (float) – End time in seconds for the chunk to extract.

  • output_audio_filename (str, optional) – Path to save the extracted audio chunk. If None, the output file will be saved in the same directory as the input file with a filename based on the chunk’s time range.

  • overwrite (bool, optional) – Currently advisory: the parameter is accepted for API compatibility but ffmpeg is always invoked to (re)write the output file. A future release may honor it by short-circuiting on an existing valid file.

Returns:

The path to the extracted audio chunk file.

Return type:

str

Raises:
  • AssertionError – If the input file is missing or invalid, or if start_time / end_time fall outside the audio’s duration.

  • ffmpeg.Error – If the underlying ffmpeg invocation fails.

Notes

Uses ffmpeg to extract a specific portion of the audio file between start_time and end_time. The input file is validated and the requested time range is checked against the actual duration.

audio_helper.main.generate_silent_audio(duration, output_audio_filename=None, sample_rate=44100, overwrite=False)[source]

Generate a silent audio file of a specified duration.

Parameters:
  • duration (float) – The duration of the silent audio file in seconds.

  • output_audio_filename (str, optional) – The path to save the generated silent audio file. If None, a default file name will be generated.

  • sample_rate (int, optional) – The sample rate of the silent audio file in Hz (default is 44100 Hz).

  • overwrite (bool, optional) – Whether to overwrite the output file if it already exists (default is False).

Returns:

The path to the generated silent audio file.

Return type:

str

Raises:
  • AssertionError – If the resulting file is missing or empty after generation.

  • ffmpeg.Error – If the underlying ffmpeg invocation fails.

Notes

Uses ffmpeg’s anullsrc filter to write a silent audio file of the specified duration and sample rate. When output_audio_filename is None, a default name is derived from duration.

audio_helper.main.get_audio_duration(file_path)[source]

Get the duration of an audio file in seconds using ffmpeg.

Parameters:

file_path (str) – Path to the audio file.

Returns:

Duration of the audio file in seconds.

Return type:

float

Raises:
  • AssertionError – If the file is missing, or if it contains no audio stream.

  • ffmpeg.Error – If ffmpeg.probe itself fails on the file.

audio_helper.main.hz_to_mel(hz)[source]

Convert a frequency in Hertz to the Mel scale.

Parameters:

hz (float) – Frequency in Hertz.

Returns:

Frequency in Mels.

Return type:

float

audio_helper.main.is_valid_audio_file(file_path)[source]

Check if the given file is a valid audio file using ffmpeg-python (ffprobe).

Parameters:

file_path (str) – Path to the audio file.

Returns:

True if the file contains a valid audio stream, False otherwise.

Return type:

bool

Notes

The function uses ffprobe to inspect the file and determine if an audio stream is present.

audio_helper.main.load_audio(file_path, target_sample_rate=None, to_mono=True, to_numpy=False, two_channels=False)[source]

Load ANY audio (or video-with-audio) file, optionally resample, convert to mono or stereo, and return as a torch.Tensor (or optionally a NumPy array).

Decoding goes through sound_converter() (ffmpeg), NOT libsndfile / soundfile — so formats libsndfile cannot open (AAC/.m4a, .opus, .webm, and the audio track of video containers) load fine. The intermediate float32 WAV is read with scipy.io.wavfile.

Parameters:
  • file_path (str) – Path to the audio file.

  • target_sample_rate (int, optional) – The target sample rate to resample the audio to. Defaults to the original sample rate.

  • to_mono (bool, optional) – Whether to convert the audio to mono (default is True).

  • to_numpy (bool, optional) – Whether to return the audio as a NumPy array (default is False). Otherwise, returns a torch.Tensor.

  • two_channels (bool, optional) – Whether to force the audio into two channels (stereo).

Returns:

  • torch.Tensor or np.ndarray – The loaded audio signal.

  • int – Sample rate of the loaded audio.

Raises:

ValueError – If ffmpeg is missing, the file cannot be read/decoded, or it carries no audio stream — always with an actionable message.

Return type:

tuple[torch.Tensor | np.ndarray, int]

audio_helper.main.mel_filter_banks(num_filters, n_fft, sample_rate, low_freq, high_freq)[source]

Compute a Mel-filter bank for given parameters.

Parameters:
  • num_filters (int) – Number of Mel filters to generate.

  • n_fft (int) – The size of the FFT (number of FFT points).

  • sample_rate (int) – The sample rate of the audio signal (in Hz).

  • low_freq (int) – The lowest frequency in the Mel filter bank (in Hz).

  • high_freq (int) – The highest frequency in the Mel filter bank (in Hz).

Returns:

A 2D array where each row is a filter in the Mel-filter bank.

Return type:

np.ndarray

audio_helper.main.mel_to_hz(mel)[source]

Convert a frequency in the Mel scale back to Hertz.

Parameters:

mel (float) – Frequency in Mels.

Returns:

Frequency in Hertz.

Return type:

float

audio_helper.main.mfcc(signal, sample_rate, num_mfcc=13, n_fft=512, num_filters=26, low_freq=0, high_freq=None)[source]

Compute Mel-frequency Cepstral Coefficients (MFCC) for an audio signal.

Parameters:
  • signal (np.ndarray) – The input audio signal as a 1D NumPy array.

  • sample_rate (int) – The sample rate of the audio signal (in Hz).

  • num_mfcc (int, optional) – The number of MFCC features to return, by default 13.

  • n_fft (int, optional) – The FFT size to use, by default 512.

  • num_filters (int, optional) – The number of Mel filters to use, by default 26.

  • low_freq (int, optional) – The lowest frequency to consider in the Mel filter bank, by default 0 Hz.

  • high_freq (int, optional) – The highest frequency to consider in the Mel filter bank, by default None (set to half the sample rate).

Returns:

A 2D NumPy array containing the computed MFCC features for each frame.

Return type:

np.ndarray

audio_helper.main.mix_room_tone(input_audio, output_audio=None, noise_db=-42.0, color='pink', sample_rate=44100, overwrite=False)[source]

Mix a constant low-level ambient noise (room tone) on top of an audio track.

Parameters:
  • input_audio (str) – Path to the input audio file (the “speech” track).

  • output_audio (str, optional) – Path to the output file. If None, <input>-roomtone.<ext> is written next to the input.

  • noise_db (float, optional) – Noise level in decibels (default -42 — inaudible but present; sit between -45 and -38 for typical post-production use). Amplitude is computed as 10 ** (noise_db / 20).

  • color (str, optional) – Noise color (default "pink"). Accepted values follow ffmpeg’s anoisesrc filter: "white", "pink", "brown" (sometimes "red"), "blue", "violet", "velvet". Pink is the standard “natural” choice for masking gaps between speech recordings.

  • sample_rate (int, optional) – Sample rate for the noise source (default 44100). The output sample rate matches whatever ffmpeg’s amix produces.

  • overwrite (bool, optional) – Whether to overwrite the output file if it already exists (default False).

Returns:

Path to the mixed output file.

Return type:

str

Notes

Standard post-production trick to homogenize a montage of disparate speech takes: perfectly silent gaps between cuts contrast unpleasantly with the speech and make every cut audible. A constant background ambience that sits ~40 dB below the speech masks the boundary while staying below the conscious hearing threshold.

The noise length is the input duration + 0.5 s (a small head-room so amix=duration=first stops exactly at the speech end without truncating the last few samples).

Examples

>>> mix_room_tone("narration.wav", "narration-rt.wav", noise_db=-42)
>>> mix_room_tone("voice.mp3", color="brown", noise_db=-38)
audio_helper.main.save_audio(signal, file_path, sample_rate=44100)[source]

Save an audio signal as a file using torchaudio (tensor) or scipy.io.wavfile (numpy).

Parameters:
  • signal (torch.Tensor or np.ndarray) – The audio signal to save.

  • file_path (str) – Path to the output audio file.

  • sample_rate (int) – The sample rate of the audio signal, in Hz.

Raises:
  • AssertionError – If signal is neither a torch.Tensor nor a numpy.ndarray.

  • ImportError – If signal is a torch.Tensor but the optional demucs extra (torch / torchaudio) is not installed.

Return type:

None

audio_helper.main.separate_sources(input_audio_file, output_folder=None, device=None, overwrite=False, nb_workers=-2, output_format='mp3')[source]

Separate an input audio file into different sources (e.g., vocals, bass, drums, other) using a pre-trained model from pytorch called DEMUCS.

Parameters:
  • input_audio_file (str) – Path to the input audio file.

  • output_folder (str, optional) – Folder to save the separated sources. If None, the output folder will be created based on the input file’s name.

  • device (str, optional) – The device on which to run the computations. If not specified, CUDA will be used if available, otherwise CPU.

  • overwrite (bool, optional) – Whether to overwrite existing files if they already exist (default is False).

  • nb_workers (int, optional) – The number of workers (threads) to use for parallel processing of segments (default is -2 which corresponds to all cores except one).

  • output_format (str, optional) – The format of the output audio files (default is ‘mp3’).

Returns:

A dictionary mapping source names (e.g., ‘vocals’, ‘bass’, etc.) to the paths of the separated audio files.

Return type:

dict

Examples

>>> separated_sources = separate_sources("input_audio.mp3", output_folder="output_folder", overwrite=True)
>>> print(separated_sources)
{'vocals': 'output_folder/vocals.mp3', 'drums': 'output_folder/drums.mp3', 'bass': 'output_folder/bass.mp3', 'other': 'output_folder/other.mp3'}

Notes

The function uses the HDEMUCS_HIGH_MUSDB_PLUS model to separate audio into its constituent sources. It processes the audio in segments with optional multithreading for parallel processing. The separated sources are saved as audio files in the specified or generated output folder.

audio_helper.main.sound_converter(input_audio, output_audio, freq=44100, channels=1, encoding='pcm_s16le', overwrite=True)[source]

Convert an audio file to the specified format using ffmpeg-python.

Parameters:
  • input_audio (str) – Path to the input audio file.

  • output_audio (str) – Path to the output audio file with the desired format extension.

  • freq (int, optional) – Output sample rate in Hz (default is 44100).

  • channels (int, optional) – Number of audio channels in the output (default is 1 for mono).

  • encoding (str, optional) – Audio codec to use for encoding the output file (default is ‘pcm_s16le’).

  • overwrite (bool)

Returns:

Path to the output audio file.

Return type:

str

Raises:
  • AssertionError – If the input audio file does not exist or is not a valid audio file.

  • ffmpeg.Error – If the underlying ffmpeg invocation fails.

Notes

The conversion is handled using a temporary file structure to manage intermediate formats. Two intermediate WAV files are used before generating the final output audio file.

audio_helper.main.sound_resemblance(audio_file_1, audio_file_2)[source]

Compute the resemblance score between two audio files using Mel-frequency Cepstral Coefficients (MFCC).

Measure the resemblance between two audio files using the correlation coefficient.

Score is between 0 and 1. The closer to 1, the more similar the signals. The closer to 0, the more different the signals.

Parameters:
  • audio_file_1 (str) – Path to the first audio file.

  • audio_file_2 (str) – Path to the second audio file.

Returns:

The resemblance score between the two audio files based on MFCC.

Return type:

float

Notes

The function computes the resemblance score between two audio files using the cosine similarity of their MFCC features.

audio_helper.main.split_audio_regularly(sound_path, chunk_folder, split_time, output_format='mp3', overwrite=False, suffix='split')[source]

Split an audio file into chunks of a specified duration.

Parameters:
  • sound_path (str) – Path to the audio file.

  • chunk_folder (str) – Path to the folder where the audio chunks will be saved.

  • split_time (float) – Duration of each audio chunk in seconds.

  • output_format (str, optional) – The format of the output audio files (default is ‘mp3’).

  • overwrite (bool, optional) – Whether to overwrite the output files if they already exist (default is False).

  • suffix (str, optional) – Suffix to add to the output audio files (default is ‘split’).

Return type:

List of audio file paths

Notes

The function uses ffmpeg to split the audio file into chunks of the specified duration.