diff options
| author | Jules Laplace <julescarbon@gmail.com> | 2018-06-06 00:59:39 +0200 |
|---|---|---|
| committer | Jules Laplace <julescarbon@gmail.com> | 2018-06-06 00:59:39 +0200 |
| commit | d3fcd1212f7214b12b04a83d03dfb129c5fbb0a4 (patch) | |
| tree | b9cede8c8b245d5dc5d3ed23d8879e603af82809 /app/client/audio/spectrum.js | |
| parent | 8c8e2e08d2ae89ba18ca05bab446e4642798dce2 (diff) | |
pix2wav paths
Diffstat (limited to 'app/client/audio/spectrum.js')
| -rw-r--r-- | app/client/audio/spectrum.js | 278 |
1 files changed, 0 insertions, 278 deletions
diff --git a/app/client/audio/spectrum.js b/app/client/audio/spectrum.js deleted file mode 100644 index f4a5444..0000000 --- a/app/client/audio/spectrum.js +++ /dev/null @@ -1,278 +0,0 @@ -import Tone from 'tone' - -import { shuffle, quantize, mod } from '../util' - -import { windows as signalWindows } from 'signal-windows' -import FFTJS from 'fft.js' - -const fft_size = 512 -const fft_overlap = fft_size / 4 - -const fft = new FFTJS(fft_size) - -function toSpectrum(pcm, sr){ - sr = sr || 44100 - const ham = signalWindows.construct('ham', fft_size) - const pcm_in = new Array(fft_size) - const pcm_length = pcm.length - const pcm_q_length = Math.ceil(pcm_length / fft_size) * fft_size - let i, j, fft_out, data = []; - for (i = -fft_size; i < pcm_q_length; i += fft_overlap) { - for (j = 0; j < fft_size; j++) { - pcm_in[j] = pcm[i+j] * ham[j] || 0 - } - fft_out = fft.createComplexArray() - fft.realTransform(fft_out, pcm_in) - fft.completeSpectrum(fft_out) - data.push(fft_out) - } - return { - data, - sr, - fft_size, - fft_overlap, - } -} - -function fromSpectrum(spec){ - const data = spec.data - const sr = spec.sr - const fft_size = spec.fft_size - const fft_overlap = spec.fft_overlap - const spec_len = data.length - - const ham = signalWindows.construct('ham', fft_size) - const out = fft.createComplexArray() - const pcm_length = fft_overlap * spec_len - - const audioBuffer = Tone.context.createBuffer(1, pcm_length, sr) - const pcm = audioBuffer.getChannelData(0); - - let i, j, u, col - - for (i = 0; i < spec_len; i++) { - col = data[i] - // for (j = fft_size; j < fft_size << 1; j++) { - // col[j] = 0 - // } - // if (i == 0) console.log(col) - fft.inverseTransform(out, col) - u = i * (fft_overlap) - for (j = 0; j < fft_size; j++) { - pcm[u+j] += out[j*2] * ham[j] || 0 - } - } - - fadeInOut(pcm, fft_size) - // console.log(pcm) - return audioBuffer -} - -function fromImageData(imageData, sr, _r, _i) { - const pixels = imageData.data - const w = imageData.width - const h = imageData.height - let data = new Array(w) - let x, y, u, v, v2 - for (y = 0; y < h; y++) { - let col = data[y] = new Float32Array(h * 4) - for (x = 0; x < w; x++) { - u = (x * (w) + y) * 4 - v = x * 2 - col[v] = (pixels[u] / 255 - 0.5) * _r - col[v+1] = (pixels[u+1] / 255 - 0.5) * _i - v2 = (h-y + h) * 2 - col[v2] = col[v] - col[v2+1] = 0 // col[v+1] - } - col[h*2] = col[h*2+1] = col[h*2-1] = col[h*2-2] = 0 - } - const spec = { - data, - sr, - fft_size, fft_overlap - } - return spec -} - -function binToHz(spec, i){ - return (i / spec.fft_size) * spec.sr -} - -function fadeInOut(pcm, fade_size){ - const pcm_length = pcm.length - let fade = 0, i - for (i = 0; i < fade_size; i++) { - fade = i / (fade_size) - fade *= fade - pcm[i] *= fade - pcm[pcm_length - i] *= fade - } -} -function rotatePhase(spec, theta){ - let { data, fft_size } = spec - let i, j, col, len = data.length - for (i = 0; i < len; i++) { - col = data[i] - for (j = 0; j < fft_size; j++) { - col[j*2+1] += theta - } - } - return spec -} - -function linearBins(spec, n){ - n = n || 1 - - let bins = [], i, q_i - for (q_i = 0; q_i < n; q_i++) { - bins[q_i] = [] - } - const step = Math.floor(spec.fft_size / n) - const len_quantize_n = quantize(spec.fft_size, n) - for (i = 0; i < len_quantize_n; i++) { - q_i = Math.floor(i/step) - bins[q_i] = bins[q_i] || [] - bins[q_i].push(i) - } - // leftover bins get put at end - for (; i < spec.fft_size; i++) { - bins[q_i].push(i) - } - return bins -} -function logarithmicBins(spec){ - let bins = [], i, j, q_i - let binCount = Math.log2(spec.fft_size) - 1 - for (i = 0, q_i = 0, j = 0; i < binCount; i++) { - j += 1 << i - bins[i] = [] - for (; q_i < j; q_i++) { - bins[i].push(q_i) - } - } - return bins -} -function concatBins(bins){ - return bins.reduce((acc, cv) => acc.concat(cv), []) -} -function reverseBins(bins){ - return bins.map( bin => bin.reverse() ) -} -function minBins(bins){ - return bins.map( bin => { - const b = bin[0] - return bin.map(() => b) - }) -} -function maxBins(bins){ - return bins.map( bin => { - const b = bin[bin.length-1] - return bin.map(() => b) - }) -} -function rotateSpectrum(spec, n){ - const { fft_size } = spec - if (n && n < 1) { - n -= 0.5 - n *= fft_size - } - n = Math.floor(n) - let order = new Array(fft_size), i - for (i = 0; i < fft_size; i++) { - order[i] = mod(i + n, fft_size/2) - } - return reorderBins(spec, order) -} -function cloneSpectrum(spec){ - const { - data, - fft_size, - sr, fft_overlap - } = spec - const spec_len = data.length - - let new_data = new Array(spec_len) - let i - for (i = 0; i < spec_len; i++) { - new_data[i] = data[i].concat() - new_data[i][2] = 0 - } - - return { - data: new_data, - fft_size, - sr, fft_overlap, - } -} -function reverseSpectrum(spec){ - let new_spec = cloneSpectrum(spec) - new_spec.data = new_spec.data.reverse() - return new_spec -} -function shuffleSpectrum(spec){ - const { fft_size } = spec - let order = new Array(fft_size), i - for (i = 0; i < fft_size; i++) { - order[i] = i - } - shuffle(order) - return reorderBins(spec, order) -} -function invertSpectrum(spec){ - const { fft_size } = spec - let order = new Array(fft_size), i - for (i = 0; i < fft_size; i++) { - order[i] = fft_size - i - 1 - } - return reorderBins(spec, order) -} -function reorderBins(spec, order){ - let new_spec = cloneSpectrum(spec) - const { - data, - sr, - fft_size, - fft_overlap, - } = spec - const spec_len = data.length - const { data: new_data } = new_spec - - let i, j, col, new_col - for (j = order.length; j < fft_size; j++) { - order[j] = j - } - - for (i = 0; i < spec_len; i++) { - col = data[i] - new_col = new_data[i] = data[i].concat() - col[0] = 0 - col[2] = 0 - col[4] = 0 - for (j = 0; j < fft_size/2; j++) { - new_col[j*2] = col[order[j]*2] - new_col[j*2+1] = col[order[j]*2+1] - } - for (; j < fft_size; j++) { - new_col[j*2] = 0 - new_col[j*2+1] = 0 - } - } - - return { - data: new_data, - sr, fft_size, fft_overlap, - } -} - -export default { - toSpectrum, fromSpectrum, fromImageData, binToHz, - fadeInOut, - cloneSpectrum, - reverseSpectrum, shuffleSpectrum, invertSpectrum, rotateSpectrum, - reorderBins, - linearBins, logarithmicBins, - concatBins, - reverseBins, minBins, maxBins, - rotatePhase, -} |
