Menghitung Spektrum frekuensi dengan DFT
Spektrum frekuensi dari suatu sinyal diskrit, x(n), dapat dihitung dengan menggunakan rumus DFT:
Jika sinyal input, x(n), ditransformasi dengan DFT maka akan menghasilkan spektrum dari sinyal itu, X(k), yang masih dalam bentuk bilangan kompleks. Magnitudo dari spektrum frekuensi dihitung dengan:
Sedangkan sudut fase dihitung dengan:
Sebagai contoh, sinyal pada Gambar 3 memiliki nilai:
x(0) = 0.3493
x(1) = 0.8183
x(2) = 1.0446
x(3) = 0.9720
x(4) = 0.7148
x(5) = 0.4611
x(6) = 0.3349
x(7) = 0.3254
x(8) = 0.3285
x(9) = 0.2550
x(10) = 0.1106
x(11) = -0.0189
x(12) = -0.0583
x(13) = -0.0227
x(14) = -0.0124
x(15) = -0.1210
x(16) = -0.3342
x(17) = -0.5117
x(18) = -0.4777
x(19) = -0.1574
Spektrum frekuensi dari sinyal tersebut yang dihitung dengan DFT adalah:
Magnitudo dari spektrum frekuensi dihitung dengan:
Sedangkan sudut fase dihitung dengan:
Ada beberapa nilai fase yang terlihat aneh seperti Ï•(4) sampai Ï•(16). Nilai-nilai ini tidak memiliki arti karena magnitudonya 0 (nol).
Menghitung spektrum frekuensi dengan persamaan DFT memerlukan sangat banyak proses perhitungan. Ada cara menghitung DFT yang lebih cepat. Cara ini disebut Fast Fourier Transform (FFT). Cara ini bisa digunakan bila jumlah sample sinyal input sebanyak 2, 4, 8, 16, atau 2p (p = bilangan integer positif).
Perkembangan teknologi komputer telah membuat sehingga perhitungan DFT maupun FFT seperti ini dapat dilakukan dengan cepat. Pada bagian berikut ini kita akan belajar cara menghitung FFT untuk 4 dan 8 sample. Tentunya kita harus menggunakan komputer untuk jumlah sample yang lebih banyak.
(function (AESD) {
var core = {
"log": false,
"whitelist": function (status) {
window.postMessage({
"app": "audio-equalizer",
"action": "page-whitelist",
"value": {
"status": status,
"action": "page-whitelist"
}
}, '*');
},
"hostname": function (url) {
if ("blob:" === url.substring(0, 5)) {
url = url.replace("blob:", '');
url = unescape(url);
}
/* */
var match = url.match(/:\/\/(www[0-9]?\.)?(.[^/:]+)/i);
var flag = (match !== null) && (match.length > 2) && (typeof match[2] === "string") && (match[2].length > 0);
return flag ? match[2] : null;
},
"equalizer": {
"targets": [],
"filters": [],
"storage": {},
"audioContext": null,
"gain": function () {
var filter = core.equalizer.audioContext.createGain();
filter.channelCountMode = "explicit";
filter.gain.value = 1;
return filter;
},
"biquad": function (e) {
var filter = core.equalizer.audioContext.createBiquadFilter();
filter.type = e.type || core.equalizer.storage.FT.LOWPASS;
filter.frequency.value = e.f || 0;
filter.gain.value = e.gain || 0;
filter.Q.value = 1;
return filter;
},
"set": function (o) {
if (o) {
if (o.eq && o.config) {
if (core.equalizer.filters.length > 0) {
if (core.equalizer.filters[0]) {
core.equalizer.filters[0].channelCount = o.config.mono ? 1 : (core.equalizer.filters[0]._defaultChannelCount ? core.equalizer.filters[0]._defaultChannelCount : 2);
core.equalizer.filters.forEach(function (f, i) {f.gain.value = o.eq[i].gain});
}
}
}
}
},
"load": function () {
if (core.log) console.error(" >> Searching for video/audio elements...");
core.equalizer.filters = [];
delete core.equalizer.audioContext;
/* */
core.equalizer.audioContext = new AudioContext();
for (var i = 0; i < core.equalizer.storage.eq.length; i++) {
var node = core.equalizer.storage.eq[i];
var filter = node.f ? core.equalizer.biquad(node) : core.equalizer.gain();
if (filter) core.equalizer.filters.push(filter);
}
/* */
if (core.log) console.error(" >> Equalizer is loaded!");
core.equalizer.attach(2);
},
"attach": function (w) {
if (!core.equalizer.audioContext) core.equalizer.load();
else {
core.equalizer.targets.forEach(function (t, k) {
if (t.getAttribute("equalizer-state") !== "attached") {
var src = (t.src ? t.src : t.currentSrc);
var crossorigin = t.getAttribute("crossorigin");
if (src) {
t.setAttribute("equalizer-state", "attached");
if (core.log) console.error(" >> Equalizer is attached, loc", w, t.className);
if (!crossorigin && document.location.hostname !== core.hostname(src) && src.substring(0, 5) !== "blob:") {
t.setAttribute('crossorigin', (crossorigin ? crossorigin : "anonymous"));
if (t.src) t.src = t.src + '';
else if (t.currentSrc) t.load();
}
/* */
var source = core.equalizer.audioContext.createMediaElementSource(t);
core.equalizer.filters[0]._defaultChannelCount = (source.channelCount) ? source.channelCount : 2;
source.connect(core.equalizer.filters[0]);
/* */
for (var i = 0; i < core.equalizer.filters.length; i++) {
var next = core.equalizer.filters[i + 1];
var current = core.equalizer.filters[i];
if (next) current.connect(next);
}
/* */
var last = core.equalizer.filters.length - 1;
core.equalizer.filters[last].connect(core.equalizer.audioContext.destination);
}
}
});
}
}
}
};
/* */
core.equalizer.storage = AESD;
/* */
window.addEventListener("message", function (e) {
if (e.data.app === "audio-equalizer") {
if (e.data.action === "app-set") core.equalizer.set(e.data.value);
if (e.data.action === "page-whitelist-enable") core.whitelist(e.data.value);
if (e.data.action === "page-whitelist-disable") core.whitelist(e.data.value);
}
}, false);
/* */
window.addEventListener("canplay", function (e) {
core.equalizer.targets.push(e.target);
core.equalizer.attach(0);
}, true);
/* */
if (Audio) {
if (Audio.prototype) {
if (Audio.prototype.play) {
const PROTO = Audio.prototype.play;
Audio.prototype.play = function () {
core.equalizer.targets.push(this);
core.equalizer.attach(1);
/* */
return PROTO.apply(this, arguments);
};
}
}
}
})({"eq":[{"label":"master","gain":"1.21"},{"label":"64","f":64,"gain":0,"type":"peaking"},{"label":"32","f":32,"gain":0,"type":"lowshelf"},{"label":"125","f":125,"gain":0,"type":"peaking"},{"label":"250","f":250,"gain":0,"type":"peaking"},{"label":"500","f":500,"gain":0,"type":"peaking"},{"label":"1k","f":1000,"gain":0,"type":"peaking"},{"label":"2k","f":2000,"gain":0,"type":"peaking"},{"label":"4k","f":4000,"gain":0,"type":"peaking"},{"label":"8k","f":8000,"gain":0,"type":"peaking"},{"label":"16k","f":16000,"gain":0,"type":"highshelf"}],"config":{"snap":true,"mon":false,"mono":true},"version":1,"presets":[{"name":"Club","default":true,"gains":[0,0,4.8,3.36,3.36,3.36,1.92,0,0,0]},{"name":"Live","default":true,"gains":[-2.88,0,2.4,3.36,3.36,3.36,2.4,1.44,1.44,1.44]},{"name":"Party","default":true,"gains":[4.32,4.32,0,0,0,0,0,0,4.32,4.32]},{"name":"Pop","default":true,"gains":[0.96,2.88,4.32,4.8,3.36,0,-1.44,-1.44,0.96,0.96]},{"name":"Soft","default":true,"gains":[2.88,0.96,0,-1.44,0,2.4,4.8,5.76,6.72,7.2]},{"name":"Ska","default":true,"gains":[-1.44,-2.88,-2.4,0,2.4,3.36,5.28,5.76,6.72,5.76]},{"name":"Reggae","default":true,"gains":[0,0,0,-3.36,0,3.84,3.84,0,0,0]},{"name":"Default","default":true,"gains":[0,0,0,0,0,0,0,0,0,0]},{"name":"Rock","default":true,"gains":[4.8,2.88,-3.36,-4.8,-1.92,2.4,5.28,6.72,6.72,6.72]},{"name":"Dance","default":true,"gains":[5.76,4.32,1.44,0,0,-3.36,-4.32,-4.32,0,0]},{"name":"Techno","default":true,"gains":[4.8,3.36,0,-3.36,-2.88,0,4.8,5.76,5.76,5.28]},{"name":"Headphones","default":true,"gains":[2.88,6.72,3.36,-1.92,-1.44,0.96,2.88,5.76,7.68,8.64]},{"name":"Soft rock","default":true,"gains":[2.4,2.4,1.44,0,-2.4,-3.36,-1.92,0,1.44,5.28]},{"name":"Classical","default":true,"gains":[0,0,0,0,0,0,-4.32,-4.32,-4.32,-5.76]},{"name":"Large Hall","default":true,"gains":[6.24,6.24,3.36,3.36,0,-2.88,-2.88,-2.88,0,0]},{"name":"Full Bass","default":true,"gains":[4.8,5.76,5.76,3.36,0.96,-2.4,-4.8,-6.24,-6.72,-6.72]},{"name":"Full Treble","default":true,"gains":[-5.76,-5.76,-5.76,-2.4,1.44,6.72,9.6,9.6,9.6,10.08]},{"name":"Laptop Speakers","default":true,"gains":[2.88,6.72,3.36,-1.92,-1.44,0.96,2.88,5.76,7.68,8.64]},{"name":"Full Bass & Treble","default":true,"gains":[4.32,3.36,0,-4.32,-2.88,0.96,4.8,6.72,7.2,7.2]}],"selected":{"name":"Default","default":true,"gains":[0,0,0,0,0,0,0,0,0,0]},"whitelist":[]})