Misalnya kita mempunyai sinyal suara dengan frekuensi 0 - 20000 Hz, namun karena suatu hal (misalnya noise) kita cuma butuh sinyal di frekuensi 700 - 1400 Hz saja, maka kita bisa menggunakan script matlab / octave ini. Script ini berjalan lancar baik pada Matlab maupun GNU Octave.
Gambar spectrogram di bawah ini membandingkan spectrogram sinyal sebelum difilter dan setelah difilter. Script untuk GNU / Octave ada di bawahnya.
|
|
Berikut script kode Octave / Matlab (link Github disini).
% demo program untuk memfilter suara pada range fekuensi oktaf tertentu % by bagustris bagustris@linuxmail.org % adopted from somewhere (forget aka lupa) % set general variables clear all; close all; clc; sf = 22050; % sample frequency nf = sf / 2; % nyquist frequency d = 1.0; % duration, ganti untuk merubah durasi suara n = sf * d; % number of samples nh = n / 2; % half number of samples % set variables for filter lf = 700; % lowest frequency, ganti dengan batas bawah bandpass hf = 1400; % highest frequency, ganti dengan batas atas bandpass lp = lf * d; % ls point in frequency domain hp = hf * d; % hf point in frequency domain % band pass filter! filter = zeros(1, n); % initializaiton by 0 filter(1, lp : hp) = 1; % filter design in real number filter(1, n - hp : n - lp) = 1; % filter design in imaginary number % make noise rand('state',sum(100 * clock)); % initialize random seed noise = randn(1, n); % Gausian noise noise = noise / max(abs(noise)); % -1 to 1 normalization % do filter s = fft(noise); % FFT s = s .* filter; % filtering s = ifft(s); % inverse FFT s = real(s); %untuk mendengarkan suara asli sound(noise,sf); pause(d+0.5); %untuk mendengarkan suara terfilter (bandpass); sound(s,sf); pause(d+0.5); %untuk menyimpan file suara dalam format .wav %ketik perintah berikut dalam command window (tanpa tanda persen%) % wavwrite(s,sf 'namafile.wav');
Untuk mengecek hasilnya (spectrum yang telah terfilter) bisa menggunakan spectrogram sbb:
figure(1); specgram(noise, 512, sf); figure(2); specgram(s, 512, sf);
Silakan dicoba. Please note the correctness and accurateness are not guaranteed.
Update 2020/06:
Dengan cara yang serupa, teknik yang sama dapat diterapkan dengan Python Scipy, yakni dengan filter butterworth. Berikut caranya (sumber: stackoverflow).
from scipy.signal import butter, lfilter def butter_bandpass(lowcut, highcut, fs, order=5): nyq = 0.5 * fs low = lowcut / nyq high = highcut / nyq b, a = butter(order, [low, high], btype='band') return b, a def butter_bandpass_filter(data, lowcut, highcut, fs, order=5): b, a = butter_bandpass(lowcut, highcut, fs, order=order) y = lfilter(b, a, data) return y def run(): import numpy as np import matplotlib.pyplot as plt from scipy.signal import freqz # Sample rate and desired cutoff frequencies (in Hz). fs = 5000.0 lowcut = 500.0 highcut = 1250.0 # Plot the frequency response for a few different orders. plt.figure(1) plt.clf() for order in [3, 6, 9]: b, a = butter_bandpass(lowcut, highcut, fs, order=order) w, h = freqz(b, a, worN=2000) plt.plot((fs * 0.5 / np.pi) * w, abs(h), label="order = %d" % order) plt.plot([0, 0.5 * fs], [np.sqrt(0.5), np.sqrt(0.5)], '--', label='sqrt(0.5)') plt.xlabel('Frequency (Hz)') plt.ylabel('Gain') plt.grid(True) plt.legend(loc='best') # Filter a noisy signal. T = 0.05 nsamples = int(T * fs) t = np.linspace(0, T, nsamples, endpoint=False) a = 0.02 f0 = 600.0 x = 0.1 * np.sin(2 * np.pi * 1.2 * np.sqrt(t)) x += 0.01 * np.cos(2 * np.pi * 312 * t + 0.1) x += a * np.cos(2 * np.pi * f0 * t + .11) x += 0.03 * np.cos(2 * np.pi * 2000 * t) plt.figure(2) plt.clf() plt.plot(t, x, label='Noisy signal') y = butter_bandpass_filter(x, lowcut, highcut, fs, order=6) plt.plot(t, y, label='Filtered signal (%g Hz)' % f0) plt.xlabel('time (seconds)') plt.hlines([-a, a], 0, T, linestyles='--') plt.grid(True) plt.axis('tight') plt.legend(loc='upper left') plt.show() run()
Hasilnya adalah sebagai berikut.
Waveform sinyal asli (atas/biru) dan setelah terfilter (bawah/oranye) |
Spektrum sinyal terfilter dengan beberepa order N yang berbeda; terlihat jeas sinyal terfilter pada frekuensi 600-1250 Hz |
Silahkan dicoba!