File size: 2,273 Bytes
2e86752
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
# 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)