const scratch = document.createElement('canvas') const scratchCtx = scratch.getContext('2d-lodpi') function spectrum(spec, x0, y0, ww, hh){ const data = spec.data const fft_size = spec.fft_size const half_fft_size = spec.fft_size / 2 const spec_len = data.length scratch.width = data.length scratch.height = half_fft_size var imageData = ctx.createImageData(scratch.width, scratch.height) var pixels = imageData.data let i, j, u, v, _r, _i, col, hsl for (i = 0; i < spec_len; i++) { col = data[i] for (j = 0; j < half_fft_size; j++) { u = ((half_fft_size - j) * spec_len + i) * 4 v = j * 2 _r = col[v] _i = mod(col[v+1], Math.PI*2) / (Math.PI*2) hsl = color.hsl2rgb((_i + 1) / 2, 1.0, 1 - Math.abs(_r / 10)) // red - real part // pixels[u] = _r * 127 + 127 // // green - imag part // pixels[u+1] = _i * 127 + 127 // // blue - magnitude // pixels[u+2] = Math.sqrt(Math.pow(_r, 2) + Math.pow(_i, 2)) * 128 + 127 // pixels[u+3] = 255 pixels[u] = hsl[0] pixels[u+1] = hsl[1] pixels[u+2] = hsl[2] pixels[u+3] = 255 } } scratchCtx.putImageData(imageData, 0, 0) var pcm_length = spec.fft_overlap * spec_len x0 = x0 * devicePixelRatio || 0 y0 = y0 * devicePixelRatio || Math.floor(h/4) ww = ww * devicePixelRatio || w hh = hh * devicePixelRatio || h/4 const width = Math.round(pcm_length / spec.sr * pixels_per_second) const height = Math.floor(hh) ctx.save() clear(1, x0, y0, w, height) ctx.drawImage(scratch, x0, y0, width, height) ctx.restore() } function raw_spectrum(spec, x0, y0, ww, hh, def_min_r, def_min_i){ const data = spec.data const fft_size = spec.fft_size const half_fft_size = spec.fft_size / 2 const spec_len = data.length const _scratch = document.createElement('canvas') const _scratchCtx = _scratch.getContext('2d-lodpi') _scratch.width = data.length _scratch.height = half_fft_size // console.log("spectrum w/h:", _scratch.width, _scratch.height) var imageData = _scratchCtx.createImageData(_scratch.width, _scratch.height) var pixels = imageData.data let i, j, u, v, _r, _i, col, hsl // let min_r = Infinity, max_r = -Infinity // let min_i = Infinity, max_i = -Infinity // determined empirically.. // let min_r = -60.4894057005308 // let max_r = 107.23800966675353 // let min_i = -59.4894057005308 // let max_i = 108.23800966675353 let min_r = -def_min_r let max_r = def_min_r let min_i = -def_min_i let max_i = def_min_i let delta_r = max_r - min_r let delta_i = max_i - min_i let mean_r = 0 let mean_i = 0 let sum_mean_r = 0, sum_mean_i = 0 let real, imag for (i = 0; i < spec_len; i++) { col = data[i] mean_r = 0 mean_i = 0 for (j = 0; j < half_fft_size; j++) { u = (j * spec_len + i) * 4 v = j * 2 real = col[v] imag = col[v+1] mean_r += real mean_i += imag _r = clamp((real - min_r) / delta_r * 255, 0, 255) _i = clamp((imag - min_i) / delta_i * 255, 0, 255) // hsl = color.hsl2rgb((_i + 1) / 2, 1.0, 1 - Math.abs(_r / 10)) pixels[u+0] = _r pixels[u+1] = _i pixels[u+2] = 127 // hsl[2] pixels[u+3] = 255 // min_r = Math.min(min_r, col[v]) // max_r = Math.max(max_r, col[v]) // min_i = Math.min(min_i, col[v]+1) // max_i = Math.max(max_i, col[v]+1) } mean_r /= half_fft_size mean_i /= half_fft_size sum_mean_r += mean_r sum_mean_i += mean_i } sum_mean_r /= spec_len sum_mean_i /= spec_len // console.log(sum_mean_r, sum_mean_i) // console.log("r:", min_r, max_r) // console.log("i:", min_i, max_i) _scratchCtx.putImageData(imageData, 0, 0) return { canvas: _scratch, imageData } }