The software (https://github.com/franzpl/sweep) has been written in the context of my bachelor thesis with the topic "On the influence of windowing of sweep signals for room impulse measurements" at the University of Rostock.
Impulse responses are an important tool to determine acoustic properties of a Device Under Test. The main requirement is that all desired frequencies cover the interesting frequency range with sufficient energy. Therefore, sweep signals and white noise are usally favored to excite DUT's. In this context sweep signals and LTI-Systems were used. However, the design of sweep signals in time domain causes ripple in the excitation spectrum at the start and stop frequency. It is possible to reduce ripple with the use of convenient windows. With this software, you can evaluate the effect of windowing of sweep signals on impulse responses under the influence of noise. This Ipython3 Notebook shows an examplary impulse response measurement (Sweep -> DUT -> System Response -> Impulse Response -> Quality of Impulse Response). You can also use the software for real measurements, because measurement module and simulation module are seperated strictly.
Let's start the simulation of an impulse response measurement!
%matplotlib inline import numpy as np import matplotlib.pyplot as plt
import generation import plotting import ir_imitation import calculation import windows import measurement_chain
fs = 44100 fstart = 1 fstop = 22050 duration = 1 # seconds pad = 5 # attach 5 seconds zeros to excitation signal
excitation = generation.log_sweep(fstart, fstop, duration, fs)
As shown in this figure, the excitation spectrum is characterized by ripple at the start and stop frequency.
plotting.plot_freq(excitation, fs, scale='db') plt.xscale('log') plt.xlim([1, fs/2]) plt.ylim([-55, -14]);
A window reduces the ringing artifacts. Fade in and fade out parameters of the window can help to produce a smoother spectrum.
fade_in = 50 # ms fade_out = 10 # ms beta = 7 # kaiser window
window = windows.window_kaiser(len(excitation), fade_in, fade_out, fs, beta) excitation_windowed = window * excitation
excitation_windowed_zeropadded = generation.zero_padding(excitation_windowed, pad, fs)
dirac = measurement_chain.convolution()
noise_level = -30 # RMS (dB) awgn = measurement_chain.additive_noise(noise_level)
Finally, the system elements must be combined. Feel free to add more elements (lowpass, bandpass, gain, ...) to the system.
system = measurement_chain.chained(dirac, awgn)
To record the system response, you have to simply pass the excitation signal to the system.
system_response = system(excitation_windowed_zeropadded)
Via the FFT and IFFT, the impulse response is calculated. That's it! A Plot with linear and dB scale show you the characteristics of the IR.
ir = calculation.deconv_process(excitation_windowed_zeropadded, system_response, fs)[:len(excitation_windowed_zeropadded)]
plotting.plot_time(ir, fs) plt.xlim([-1, 5]) plt.ylim([-0.1, 1.1]);
plotting.plot_time(ir, fs, scale='db') plt.xlim([-1, 5]) plt.ylim([-60, 2]);
The 'Peak to Noise Ratio' provides information about the quality of the IR.
pnr = calculation.pnr_db(ir, ir[fs:pad*fs]) print(str(pnr), 'dB')