summaryrefslogtreecommitdiff
path: root/app/client/audio/spectrum.js
diff options
context:
space:
mode:
authorJules Laplace <julescarbon@gmail.com>2018-06-06 00:59:39 +0200
committerJules Laplace <julescarbon@gmail.com>2018-06-06 00:59:39 +0200
commitd3fcd1212f7214b12b04a83d03dfb129c5fbb0a4 (patch)
treeb9cede8c8b245d5dc5d3ed23d8879e603af82809 /app/client/audio/spectrum.js
parent8c8e2e08d2ae89ba18ca05bab446e4642798dce2 (diff)
pix2wav paths
Diffstat (limited to 'app/client/audio/spectrum.js')
-rw-r--r--app/client/audio/spectrum.js278
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,
-}