Интерполяция между двумя частотами в NumPy - PullRequest
0 голосов
/ 07 июня 2019

Я хочу создать синусоидальную волну, которая начинается с частоты f1 и заканчивается на частоте f2.Вот код, который я использовал:

import matplotlib.pyplot as plt
import numpy as np

def freq_interp(dur,f1,f2,fs=44100):
    num_samples = fs*dur
    t = np.linspace(0,dur,num_samples)
    a = np.linspace(0,1,num_samples)
    f = (1-a)*f1+a*f2 # interpolate
    samples = np.cos(2*np.pi*f*t)
    return samples,f

Когда я пытаюсь сгенерировать файл WAV или просто построить STFT сигнала, я получаю неожиданный результат.Например, я использовал код ниже:

def plot_stft(sig,fs=44100):
    f, t, Zxx = signal.stft(sig,fs=fs,nperseg=2000)
    plt.pcolormesh(t, f, np.abs(Zxx), vmin=0, vmax=0.1)
    plt.ylim(0,2000)
    plt.title('STFT Magnitude')
    plt.ylabel('Frequency [Hz]')
    plt.xlabel('Time [sec]')
    plt.show()

s,f = freq_interp(dur=2,f1=1,f2=1000)
plt.plot(f)
plt.show()
plot_stft(s)

s,f = freq_interp(dur=2,f1=1000,f2=1)
plt.plot(f)
plt.show()
plot_stft(s)

Я получаю эти графики: enter image description here

Проблема более очевидна во втором ряду.Где частота отскочила назад при t = 1 с.Также в первом ряду вы можете видеть, что частота поднялась до 2000 Гц, что неправильно.Любая идея, почему это происходит и как я могу это исправить?

1 Ответ

1 голос
/ 07 июня 2019

Синусоида - это грех (p (t)), где p (t) - фазовая функция. И функция частоты f (t) = d p (t) / dt, чтобы вычислить p (t), вы сначала вычисляете f (t), а затем интегрируете его. Простейший метод интеграции - использование cumsum().

def freq_interp(dur,f1,f2,fs=44100):
    num_samples = int(fs*dur)
    t = np.linspace(0,dur,num_samples)
    f = np.linspace(f1, f2, num_samples)
    phase = 2 * np.pi * np.cumsum(f) / fs
    samples = np.cos(phase)
    return t, samples
...