tuning-alterer / audio_tuner.py
vericudebuget's picture
Create audio_tuner.py
2e86752 verified
# audio_tuner.py
from pydub import AudioSegment
def change_audio_tuning(audio_filepath, initial_tuning_hz, desired_tuning_hz):
"""
Changes the speed of an audio file to match a desired tuning.
This function adjusts the playback speed of the audio, which in turn
changes its pitch, to move from an initial tuning to a desired tuning.
Args:
audio_filepath (str): Path to the input audio file.
initial_tuning_hz (float): The initial tuning frequency in Hz (e.g., 440).
desired_tuning_hz (float): The desired tuning frequency in Hz (e.g., 432).
Returns:
(int, numpy.ndarray): A tuple containing the new sample rate and the
audio data as a NumPy array for Gradio compatibility.
"""
# --- Input Validation ---
if not audio_filepath:
raise ValueError("No audio file provided.")
if not initial_tuning_hz or not desired_tuning_hz:
raise ValueError("Initial and desired tuning frequencies must be provided.")
if initial_tuning_hz <= 0 or desired_tuning_hz <= 0:
raise ValueError("Tuning frequencies must be positive values.")
# --- Processing ---
# Calculate the speed multiplier required to change the pitch
speed_multiplier = desired_tuning_hz / initial_tuning_hz
# Load the audio file using pydub
sound = AudioSegment.from_file(audio_filepath)
# A simple way to change speed without pitch correction is to change the frame rate
new_frame_rate = int(sound.frame_rate * speed_multiplier)
# Create a new audio segment with the modified frame rate
tuned_sound = sound._spawn(sound.raw_data, overrides={"frame_rate": new_frame_rate})
# Set the frame rate back to the original to ensure proper playback speed in most players,
# effectively resampling the audio.
tuned_sound = tuned_sound.set_frame_rate(sound.frame_rate)
# --- Output for Gradio ---
# Gradio audio component expects a tuple of (sample_rate, numpy_array)
# The sample rate is the original rate after resampling.
# The audio data is converted to a NumPy array.
import numpy as np
samples = np.array(tuned_sound.get_array_of_samples()).astype(np.int16)
return (tuned_sound.frame_rate, samples)