示例#1
0
def plot_fr(b, a, ops, func, title):
    plt.figure()
    legend = []
    for op in ops:
        b_p, a_p = func(b, a, op)
        adsp.plot_magnitude_response(b_p,
                                     a_p,
                                     worN=2 * np.logspace(1, 4, 500),
                                     fs=fs)
        legend.append(f'A = {op}')

    plt.grid()
    plt.xlim(20, 20000)
    plt.title(title)
    plt.legend(legend)
    plt.xlabel('Frequency [Hz]')
    plt.ylabel('Magnitude [dB]')
sweep = adsp.sweep_log (20, 22000, 1, fs)

legend = []
freqs = np.logspace (1, 3.4, num=1000, base=20)
for g in [0.00001, 0.04, 0.2, 1.0]:
    cur_sweep = np.copy (sweep) * g
    y = np.copy (cur_sweep)

    filter = NLFeedback()
    filter.setCoefs (b, a)
    filter.fb_lambda = lambda a,x : a*np.tanh (x)
    y = filter.process_block (y)

    h = adsp.normalize (adsp.sweep2ir (cur_sweep, y))
    adsp.plot_magnitude_response (h, [1], worN=freqs, fs=fs)

    if g < 0.0001: legend.append ('Linear')
    else: legend.append ('Nonlinear (gain={})'.format (g))

plt.title ('Lowpass Filter with nonlinear feedback')
plt.legend (legend)
plt.ylim (-10)

#%% [markdown]
# From the above plot, it seems pretty obvious that as the gain of the input
# signal increases, the resonant frequency of the filter seems to shift
# as well. Vadim Zavalishin describes a similar effect that occurs when
# adding nonlinear elements to the feedback paths of a ladder filter, and
# he has a useful way of thinking about this phenomenon: "as audio-rate
# modulation of the cutoff (frequency)"[1]. The result of this modulation
示例#3
0
    return signal.bilinear(b_s, a_s, fs=fs)

def new_fr_plot():
    plt.figure()
    plt.xlabel('Frequency [Hz]')
    plt.ylabel('Magnitude [dB]')
    plt.grid()
    plt.xlim(20, 20000)
    
# Feedback gain plot
new_fr_plot()
legend = []
for G in [0.0, 0.25, 0.5, 0.75, 0.9]:
    b, a = calc_fb_coefs(10000, G)
    adsp.plot_magnitude_response(b, a, worN=worN, fs=fs)
    legend.append(f'Feedback = {G}')

plt.title('Feedback Stage Response at various feedback gains')
plt.legend(legend)

# LFO plot
new_fr_plot()
legend = []
for lfo in [-1, 0, 0.5, 0.9, 1.0]:
    b, a = calc_fb_coefs(lfo2res(lfo), 0.5)
    adsp.plot_magnitude_response(b, a, worN=worN, fs=fs)
    legend.append(f'LFO = {lfo}')

plt.title('Feedback Stage Response at various LFO values')
plt.legend(legend, loc='lower left')
示例#4
0
import numpy as np
import matplotlib.pyplot as plt
import audio_dspy as adsp

FS = 48000

worN = np.logspace(1, 2, 500)

# 12 dB/Oct filters
freq = [45, 40, 35]
legend = []
for fc in freq:
    b, a = adsp.design_HPF2(fc, 0.7071, FS)
    adsp.plot_magnitude_response(b, a, fs=FS, worN=worN)
    legend.append(f'12 dB Slope, fc={fc}')

# 24 dB/Oct fitler
freq = 35
sos = adsp.design_HPFN(freq, 0.7071, 4, FS)
adsp.plot_magnitude_response_sos(sos, fs=FS, worN=worN)
legend.append(f'24 dB Slope, fc={freq}')

plt.grid(which='both')
plt.ylim([-30, 3])

plt.legend(legend, loc='lower right')
plt.title('DC Blockers Comparison')
plt.show()
x = np.sin(2 * np.pi * np.arange(N) * freq / fs)

y = NLAllpass(x, func=lambda x: 3 * x)

# %%
ind = 3000
plt.plot(x[:ind])
plt.plot(y[:ind])

plt.title('Sine Response for Nonlinear Allpass')
plt.xlabel('Time [samples]')
plt.legend(['Dry', 'Wet'])

# %%
worN = np.logspace(1, 3.3, num=500, base=20)
adsp.plot_magnitude_response(y, [1], worN=worN, fs=fs, norm=True)
plt.ylim(-100)
plt.title('Nonlinear Allpass Harmonic Response')

# %% [markdown]
# ## Adding more nonlinearity
#
# One thing I noticed after playing around with these nonlinear allpass filters
# for a little while, is that when increase the gain factor for the filter
# coefficients, the filter started become very harsh, and exhibit a "wrapping"
# effect on the input sine wave.

# %%
y = NLAllpass(x, func=lambda x: 15 * x)

ind = 3000
示例#6
0
def inches2meters(inches):
    return inches / 39.370078740157


def deg2rad(deg):
    return deg * np.pi / 180


tape_width = inches2meters(0.25)
tape_speed = inches2meters(15)
azimuth_angle = deg2rad(5)

delay_dist = (tape_width / 2) * np.sin(azimuth_angle)
delay_ms = 1000 * (delay_dist / tape_speed)
print(delay_ms)

FS = 48000
delay_samp = (delay_ms / 1000) * FS
print(delay_samp)

FILT_SAMP = delay_samp / 16
x = np.arange(
    FILT_SAMP)  # np.pi * np.arange(-FILT_SAMP, FILT_SAMP) / FILT_SAMP
p = 1
h = -(6.0 / FILT_SAMP**3) * x * (x - FILT_SAMP)

# plt.plot(h)
adsp.plot_magnitude_response(h, [1], fs=FS)
plt.ylim(-60)
plt.show()
示例#7
0
        lifetime = r.gauss(1.2*pred_lifetime, 0.1*pred_lifetime)

        if (age > lifetime): # failure
            return r.uniform(0.0, 1.0) * 15.0*val + 0.5*val

    return val * (1 - 0.025 * np.log10(age))

def design_SKLPF(R, C, R1, R2, fs, age=1, temp=300, ageRs=True, ageCs=True, failCs=True):
    fc = 1.0 / (2 * np.pi * getResVal(R, age if ageRs else 1, temp) * getCapVal(C, age if ageCs else 1, temp, fail=failCs))
    Q = 1.0 / (2 - (getResVal(R2, age if ageRs else 1, temp) / getResVal(R1, age if ageRs else 1, temp)))

    return adsp.design_LPF2(fc, Q, fs)

fs = 44100
b, a = design_SKLPF(4.7e-9, 33800, 1000, 1500, fs)
adsp.plot_magnitude_response(b, a, fs=fs)
plt.ylim(-60)
plt.title('Sallen-Key LPF')

# %% [markdown]
# ## Resistor Aging
#
# As a resistor grows old, the resistance tends to
# increase. For a typical thin-film resistor, the
# age dependence is described by [[1]]:
#
# $$
# \frac{\Delta R}{R} = (1.51 \times 10^{12})\ 
# t^{0.61}\  e^{- 15,087 / T}
# $$
#
y = np.copy(sweep)
y_NL = np.copy(sweep)

procLin = FBProc()
procLin.feedback_lambda = lambda x: 0.5 * (2 * x)
y = procLin.process_block(y)

procNL = FBProc()
procNL.feedback_lambda = lambda x: 0.5 * adsp.soft_clipper(2 * x)
y_NL = procNL.process_block(y_NL)

#%%
h = adsp.sweep2ir(sweep, y)
h_NL = adsp.sweep2ir(sweep, y_NL)

adsp.plot_magnitude_response(h, [1], fs=fs)
adsp.plot_magnitude_response(h_NL, [1], fs=fs)

#%%
plt.plot(sweep, y_NL)

#%% [markdown]
# $$
# y[n] = x[n] + y[n-1] * a_1
# $$


#%%
def q2damp(freq, Q, fs):
    alpha = np.sin(2 * np.pi * freq / fs) / (2 * Q)
    return np.sqrt(1 - alpha) / np.sqrt(1 + alpha)
示例#9
0
impact_wavs = []
plt.figure()
# plt.title('Waterbottle Impacts')
for i in impacts:
    impact_wavs.append(get_impact_response(i))
plt.legend()
plt.xlabel('Time [samples]')
plt.ylabel('Magnitude')
plt.grid()
plt.savefig('Figures/Impacts_time.png')

# %%
worN = np.logspace(1, 3.35, base=20, num=1000)
legend = []
plt.figure()
# plt.title('Waterbottle Impacts Frequency Responses')
for idx, wav in enumerate(impact_wavs):
    adsp.plot_magnitude_response(wav, [1], worN=worN, fs=48000, norm=True)
    legend.append(impacts[idx]['name'])
    # wavfile.write('Impacts/Wavs/{}.wav'.format(impacts[idx]['name']), 48000, wav)

plt.legend(legend)
plt.ylim(-45)
plt.xlim(20, 5000)
plt.grid()
plt.savefig('Figures/Impacts_freq.png')

plt.show()

# %%