Skip to content

Commit e4716c9

Browse files
committed
DataEffect
1 parent b28f455 commit e4716c9

File tree

3 files changed

+176
-51
lines changed

3 files changed

+176
-51
lines changed

editor/index.js

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ import WebGLVisualizer from './visualizers/WebGLVisualizer.js';
1010
import CanvasVisualizer from './visualizers/CanvasVisualizer.js';
1111
import NullVisualizer from './visualizers/NullVisualizer.js';
1212

13-
//import DataEffect from './visualizers/effects/DataEffect.js';
13+
import DataEffect from './visualizers/effects/DataEffect.js';
1414
import FFTEffect from './visualizers/effects/FFTEffect.js';
1515
//import SampleEffect from './visualizers/effects/SampleEffect.js';
1616
import VSAEffect from './visualizers/effects/VSAEffect.js';
@@ -252,7 +252,7 @@ async function main() {
252252
g_vsaVisualizer = new WebGLVisualizer(gl, [g_vsaEffect]);
253253

254254
const effects = [
255-
//new DataEffect(gl),
255+
new DataEffect(gl),
256256
// ...(showSample ? [new SampleEffect(gl)] : []),
257257
//new WaveEffect(gl),
258258
new FFTEffect(gl),
@@ -599,7 +599,7 @@ async function setExpressions(expressions, resetToZero) {
599599
setURL();
600600
}
601601

602-
function compile(text, resetToZero) {
602+
async function compile(text, resetToZero) {
603603
const sections = splitBySections(text);
604604
if (sections.default || sections.channel1) {
605605
const expressions = [sections.default?.body || sections.channel1?.body];
@@ -609,7 +609,10 @@ function compile(text, resetToZero) {
609609
if (resetToZero) {
610610
g_visualizer.reset();
611611
}
612-
setExpressions(expressions, resetToZero);
612+
await setExpressions(expressions, resetToZero);
613+
if (resetToZero) {
614+
g_visualizer.reset();
615+
}
613616
}
614617
if (sections.vsa) {
615618
g_vsaEffect.setURL(sections.vsa.argString);

editor/visualizers/effects/DataEffect.js

Lines changed: 67 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,11 @@
11
import * as twgl from '../../../js/twgl-full.module.js';
2-
import ByteBeatNode from '../../../src/ByteBeatNode.js';
32
import { drawEffect } from './effect-utils.js';
43

54
const colorBlue = new Float32Array([0, 0, 1, 1]);
65
const colorGray = new Float32Array([0.25, 0.25, 0.25, 1]);
76

7+
const kChunkSize = 1024;
8+
89
export default class DataEffect {
910
constructor(gl) {
1011
this.programInfo = twgl.createProgramInfo(gl, [
@@ -52,24 +53,17 @@ export default class DataEffect {
5253
wrap: gl.CLAMP_TO_EDGE,
5354
}),
5455
];
56+
this.dataCursor = 0;
57+
this.data = [];
5558
}
5659
reset(gl) {
57-
this.dataTime = 0;
58-
this.dataPos = 0;
5960
for (let i = 0; i < this.dataWidth; ++i) {
6061
this.dataBuf[i] = 0;
6162
}
62-
for (const tex of this.dataTex) {
63-
gl.bindTexture(gl.TEXTURE_2D, tex);
64-
gl.texImage2D(
65-
gl.TEXTURE_2D, 0, gl.LUMINANCE, this.dataWidth, 1, 0,
66-
gl.LUMINANCE, gl.UNSIGNED_BYTE, this.dataBuf);
67-
}
63+
this.resize(gl);
6864
}
69-
resize(gl) {
70-
this.dataContext = ByteBeatNode.createContext();
71-
this.dataStack = ByteBeatNode.createStack();
7265

66+
async resize(gl) {
7367
this.dataWidth = gl.drawingBufferWidth;
7468
const dataBuf = new Uint8Array(this.dataWidth);
7569
this.dataPos = 0;
@@ -82,15 +76,74 @@ export default class DataEffect {
8276
}
8377
this.dataBuf = dataBuf;
8478
this.dataTime = 0;
79+
this.oldDataTime = 0;
80+
this.data = new Map();
81+
this.state = 'init';
82+
}
8583

84+
async #getData(byteBeat) {
85+
this.updating = true;
86+
const start = Math.ceil(this.dataTime / kChunkSize) * kChunkSize;
87+
const numChannels = byteBeat.getNumChannels();
88+
const dataP = [];
89+
for (let channel = 0; channel < numChannels; ++channel) {
90+
dataP.push(byteBeat.getSamplesForTimeRange(start, start + kChunkSize, 1, this.dataContext, this.dataStack, channel));
91+
}
92+
const data = await Promise.all(dataP);
93+
const chunkId = start / kChunkSize;
94+
this.data.set(chunkId, data);
95+
this.updating = false;
8696
}
97+
98+
#update(byteBeat) {
99+
const noData = this.data.length === 0;
100+
const passingHalfWayPoint = (this.oldDataTime % kChunkSize) < kChunkSize / 2 && (this.dataTime % kChunkSize) >= kChunkSize / 2;
101+
const passingChunk = (this.oldDataTime % kChunkSize) === kChunkSize - 1 && this.dataTime % kChunkSize === 0;
102+
const oldChunkId = this.oldDataTime / kChunkSize | 0;
103+
this.oldDataTime = this.dataTime;
104+
if (passingChunk) {
105+
this.data.delete(oldChunkId);
106+
}
107+
if (!this.updating && (noData || passingHalfWayPoint)) {
108+
this.#getData(byteBeat);
109+
}
110+
}
111+
112+
async #init(byteBeat) {
113+
if (this.dataContext) {
114+
byteBeat.destroyContext(this.dataContext);
115+
byteBeat.destroyStack(this.dataStack);
116+
}
117+
this.dataContext = await byteBeat.createContext();
118+
this.dataStack = await byteBeat.createStack();
119+
await this.#getData(byteBeat);
120+
this.state = 'running';
121+
}
122+
87123
render(gl, commonUniforms, byteBeat) {
124+
if (this.state === 'init') {
125+
this.state = 'initializing';
126+
this.#init(byteBeat);
127+
}
128+
if (this.state !== 'running') {
129+
return;
130+
}
131+
this.#update(byteBeat);
88132
const numChannels = byteBeat.getNumChannels();
89133

90134
const {uniforms, programInfo, bufferInfo} = this;
91135

136+
const chunkId = this.dataTime / kChunkSize | 0;
137+
const chunk = this.data.get(chunkId);
138+
const ndx = this.dataTime % kChunkSize;
92139
for (let channel = 0; channel < numChannels; ++channel) {
93-
this.dataPixel[0] = Math.round(byteBeat.getSampleForTime(this.dataTime++, this.dataContext, this.dataStack, channel) * 127) + 127;
140+
try {
141+
const ch = chunk[channel];
142+
const sample = ch[ndx];
143+
this.dataPixel[0] = Math.round(sample * 127) + 127;
144+
} catch {
145+
//
146+
}
94147
gl.bindTexture(gl.TEXTURE_2D, this.dataTex[channel]);
95148
gl.texSubImage2D(gl.TEXTURE_2D, 0, this.dataPos, 0, 1, 1, gl.LUMINANCE, gl.UNSIGNED_BYTE, this.dataPixel);
96149
this.dataPos = (this.dataPos + 1) % this.dataWidth;
@@ -107,5 +160,6 @@ export default class DataEffect {
107160
gl.disable(gl.BLEND);
108161
}
109162
}
163+
++this.dataTime;
110164
}
111165
}

0 commit comments

Comments
 (0)