请给出用Python实现的TDPS算法的代码,实现音频的升调不变速,允许使用Numpy库与Scipy库。
时间: 2024-04-30 13:18:24 浏览: 117
下面是用Python实现的TDPS算法的代码,实现音频的升调不变速:
```
import numpy as np
from scipy.signal import resample_poly
def tdps(audio, sr, factor):
"""
Implementation of the Time Domain Pitch Shift (TDPS) algorithm.
Parameters:
audio (ndarray): audio signal
sr (int): sampling rate of audio signal
factor (float): pitch shift factor, e.g. 1.5 for up one and a half steps
Returns:
audio_shifted (ndarray): pitch shifted audio signal
"""
# Divide the audio signal into frames of 2048 samples
frame_size = 2048
hop_size = 1024
num_frames = int(np.ceil(len(audio) / hop_size))
audio = np.pad(audio, (0, frame_size - len(audio) % frame_size), 'constant', constant_values=0)
frames = np.zeros((num_frames, frame_size))
for i in range(num_frames):
frames[i] = audio[i * hop_size:i * hop_size + frame_size]
# Apply window function to each frame
window = np.hanning(frame_size)
frames = frames * window
# Compute the FFT of each frame
fft_frames = np.fft.rfft(frames, axis=1)
# Compute the phase difference between frames
phase_diff = np.diff(np.unwrap(np.angle(fft_frames)), axis=0)
# Compute the frequency scaling factor for each frame
freq_scale = np.ones((num_frames - 1, frame_size // 2 + 1))
for i in range(num_frames - 1):
freq_scale[i] = np.exp(1j * phase_diff[i] * factor)
# Apply the frequency scaling to the FFT of each frame
fft_frames_shifted = np.zeros_like(fft_frames)
fft_frames_shifted[0] = fft_frames[0]
fft_frames_shifted[1:] = fft_frames[1:-1] * freq_scale
fft_frames_shifted[-1] = fft_frames[-1]
# Compute the inverse FFT of each frame to obtain the pitch shifted audio
audio_shifted = np.zeros_like(audio)
for i in range(num_frames):
audio_shifted[i * hop_size:i * hop_size + frame_size] += np.fft.irfft(fft_frames_shifted[i], n=frame_size)
# Resample the pitch shifted audio to the original sampling rate
audio_shifted = resample_poly(audio_shifted, int(sr * factor), sr, axis=0)
return audio_shifted
```
其中,`audio`是输入的音频信号,`sr`是音频信号的采样率,`factor`是升调的倍数。函数首先将音频信号划分为2048个样本的帧,然后对每个帧应用汉宁窗函数,并计算每个帧的FFT。接下来,计算相邻帧之间的相位差,以及每个帧的频率缩放因子。然后将频率缩放应用到每个帧的FFT上,并计算每个帧的IFFT以获得升调的音频信号。最后,将升调的音频信号重新采样到原始采样率。
阅读全文