diff --git a/rad/main.js b/rad/main.js index 7c550e1..04747e7 100644 --- a/rad/main.js +++ b/rad/main.js @@ -46,68 +46,29 @@ async function redrawRT() { let time = Date.now(); is_drawing = true; + let draw_sg = (sg) => utils.drawSpectrogram(canvas, sg, + { fs_full: true, db_log: s => s ** (1 / conf.brightness) }); + try { log('decoding audio file:', audio_file.name); let audio_signal = await utils.decodeAudioFile(audio_file, conf.sampleRate); - - log('computing spectrogram'); let spectrogram = await utils.computePaddedSpectrogram(audio_signal, { num_frames: conf.numFrames, frame_size: conf.frameSize, }); - // await utils.drawSpectrogram(canvas, spectrogram, { fs_full: true }); - // throw new Error('dbg224'); - - log('computing autocorrelation'); let correlogram = computeAutoCorrelation(spectrogram); - // await utils.drawSpectrogram(canvas, correlogram, { fs_full: true }); - // throw new Error('dbg224'); - let diskogram = createDiskSpectrogram(correlogram); - // await utils.drawSpectrogram(canvas, diskogram, { fs_full: true }); - // throw new Error('dbg224'); - - log('computing radon transform'); let radogram = utils.computeFFT2D(diskogram); - - log('drawing radon sinogram'); - utils.drawSpectrogram(canvas, radogram, - { fs_full: true, rgb_fn: s => [s * 25, s * 5, s * 1], db_log: s => s ** (1 / conf.brightness) }); - + await draw_sg(radogram); + } finally { utils.shiftCanvasData(canvas, { dx: canvas.width / 2 }); utils.shiftCanvasData(canvas, { dy: canvas.height / 2 }); - } finally { is_drawing = false; } log('done in', Date.now() - time, 'ms'); } -function createSpectrogramFilter(sample_rate, freq_hz_min, freq_hz_max, multiplier = 1.0) { - return (f, fs) => { - let hz = min(f, fs - f) / fs * sample_rate; - return multiplier * utils.hann((hz - freq_hz_min) / (freq_hz_max - freq_hz_min)); - }; -} - -function applySpectrogramFilter(spectrogram, filter_fn) { - let [nf, fs] = spectrogram.dimensions; - let output = spectrogram.clone(); - - for (let t = 0; t < nf; t++) { - let src = spectrogram.subtensor(t); - let res = output.subtensor(t); - - for (let f = 0; f < fs; f++) { - let x = filter_fn(f, fs); - res.array[2 * f + 0] = x * src.array[2 * f + 0]; - res.array[2 * f + 1] = x * src.array[2 * f + 1]; - } - } - - return output; -} - function computeAutoCorrelation(spectrogram) { let output = spectrogram.clone(); let [nf, fs] = spectrogram.dimensions; @@ -139,24 +100,21 @@ function createDiskSpectrogram(spectrogram, disk_size) { let sqr2 = (x) => x * x; let disk = new utils.Float32Tensor([ds, ds, 2]); - for (let y = -ds / 2; y < ds / 2; y++) { - for (let x = -ds / 2; x < ds / 2; x++) { - let r = sqrt(x * x + y * y) / ds * 2; // 0..1 - let a = atan2(y, x) / PI; // -1..1 - if (r == 0 || r >= 1) continue; - - let t = min(nf - 1, r * nf | 0); // frame id - let f = ((abs(a) * fs / 2 | 0) + fs) % fs; // freq id - dcheck(t >= 0 && t < nf); - dcheck(f >= 0 && f < fs); + for (let t = 0; t < nf; t++) { + for (let f = -fs / 2; f < fs / 2; f++) { + let r = t / nf; + let a = f / fs * 2 * Math.PI; + let y = r * Math.sin(a) * ds / 2 | 0; + let x = r * Math.cos(a) * ds / 2 | 0; let yx = ((y + ds) % ds * ds + (x + ds) % ds) * 2; - let tf = (t * fs + f) * 2; + let tf = (t * fs + (f + fs) % fs) * 2; + dcheck(yx >= 0 && tf >= 0); let re = spectrogram.array[tf + 0]; let im = spectrogram.array[tf + 1]; - disk.array[yx + 0] = re; - disk.array[yx + 1] = im; + disk.array[yx + 0] += re; // re*re+im*im; + disk.array[yx + 1] += im; // 0; } }