Skip to content

Commit e2d48bd

Browse files
committed
WaveEffect
1 parent e4716c9 commit e2d48bd

File tree

4 files changed

+58
-34
lines changed

4 files changed

+58
-34
lines changed

editor/index.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ 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';
17-
//import WaveEffect from './visualizers/effects/WaveEffect.js';
17+
import WaveEffect from './visualizers/effects/WaveEffect.js';
1818

1919
import songList from './songList.js';
2020

@@ -254,7 +254,7 @@ async function main() {
254254
const effects = [
255255
new DataEffect(gl),
256256
// ...(showSample ? [new SampleEffect(gl)] : []),
257-
//new WaveEffect(gl),
257+
new WaveEffect(gl),
258258
new FFTEffect(gl),
259259
];
260260
g_visualizers = [

editor/visualizers/effects/DataEffect.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -87,7 +87,7 @@ export default class DataEffect {
8787
const numChannels = byteBeat.getNumChannels();
8888
const dataP = [];
8989
for (let channel = 0; channel < numChannels; ++channel) {
90-
dataP.push(byteBeat.getSamplesForTimeRange(start, start + kChunkSize, 1, this.dataContext, this.dataStack, channel));
90+
dataP.push(byteBeat.getSamplesForTimeRange(start, start + kChunkSize, kChunkSize, this.dataContext, this.dataStack, channel));
9191
}
9292
const data = await Promise.all(dataP);
9393
const chunkId = start / kChunkSize;

editor/visualizers/effects/WaveEffect.js

Lines changed: 42 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
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 colorRed = new Float32Array([1, 0, 0, 1]);
@@ -44,13 +43,11 @@ export default class WaveEffect {
4443
this.position = 0;
4544
}
4645
resize(gl) {
47-
this.beatContext = ByteBeatNode.createContext();
48-
this.beatStack = ByteBeatNode.createStack();
49-
5046
const width = gl.drawingBufferWidth;
5147
const lineHeight = new Float32Array(width);
5248
const column = new Float32Array(width);
5349

50+
this.state = 'init';
5451
this.width = width;
5552
this.position = 0;
5653
this.then = performance.now();
@@ -80,8 +77,46 @@ export default class WaveEffect {
8077
this.bufferInfoR.numElements = width;
8178
}
8279
}
80+
async #update(gl, byteBeat, elapsedTimeMS) {
81+
if (this.state === 'init') {
82+
this.state = 'initializing';
83+
if (this.beatContext) {
84+
byteBeat.destroyContext(this.beatContext);
85+
byteBeat.destroyStack(this.beatStack);
86+
}
87+
this.beatContext = await byteBeat.createContext();
88+
this.beatStack = await byteBeat.createStack();
89+
this.state = 'running';
90+
}
91+
if (this.state === 'running') {
92+
this.state = 'waiting';
93+
const {bufferInfoL, bufferInfoR, beatContext: context, beatStack: stack} = this;
94+
const numChannels = byteBeat.getNumChannels();
95+
const startTime = this.position;
96+
const endTime = startTime + elapsedTimeMS * 0.001 * byteBeat.getDesiredSampleRate() | 0;
97+
this.position = endTime;
98+
const dataP = [];
99+
for (let channel = 0; channel < numChannels; ++channel) {
100+
dataP.push(byteBeat.getSamplesForTimeRange(
101+
startTime,
102+
endTime,
103+
this.lineHeightL.length,
104+
context,
105+
stack,
106+
channel,
107+
));
108+
}
109+
const data = await Promise.all(dataP);
110+
for (let channel = 0; channel < numChannels; ++channel) {
111+
const bufferInfo = channel ? bufferInfoR : bufferInfoL;
112+
gl.bindBuffer(gl.ARRAY_BUFFER, bufferInfo.attribs.height.buffer);
113+
gl.bufferSubData(gl.ARRAY_BUFFER, 0, data[channel].subarray(0, this.lineHeightL.length));
114+
}
115+
this.state = 'running';
116+
}
117+
}
83118
render(gl, commonUniforms, byteBeat) {
84-
const {uniforms, programInfo, bufferInfoL, bufferInfoR, beatContext: context, beatStack: stack} = this;
119+
const {uniforms, programInfo, bufferInfoL, bufferInfoR} = this;
85120
const numChannels = byteBeat.getNumChannels();
86121

87122
const targetTimeMS = 1000 / (48000 / 4096);
@@ -90,24 +125,8 @@ export default class WaveEffect {
90125
const run = elapsedTimeMS >= targetTimeMS;
91126
if (run) {
92127
this.then = now;
93-
if (byteBeat.isRunning() ) {
94-
const startTime = this.position;
95-
const endTime = startTime + elapsedTimeMS * 0.001 * byteBeat.getDesiredSampleRate() | 0;
96-
const duration = (endTime - startTime);
97-
98-
this.position = endTime;
99-
for (let channel = 0; channel < numChannels; ++channel) {
100-
const bufferInfo = channel ? bufferInfoR : bufferInfoL;
101-
102-
const dst = channel ? this.lineHeightR : this.lineHeightL;
103-
for (let i = 0; i < dst.length; ++i) {
104-
const position = startTime + i * duration / dst.length | 0;
105-
dst[i] = byteBeat.getSampleForTime(position, context, stack, channel);
106-
}
107-
108-
gl.bindBuffer(gl.ARRAY_BUFFER, bufferInfo.attribs.height.buffer);
109-
gl.bufferSubData(gl.ARRAY_BUFFER, 0, dst);
110-
}
128+
if (byteBeat.isRunning()) {
129+
this.#update(gl, byteBeat, elapsedTimeMS);
111130
}
112131
}
113132

src/ByteBeatNode.js

Lines changed: 13 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -62,8 +62,13 @@ class BeatWorkletProcessor extends AudioWorkletProcessor {
6262
const transferables = [];
6363
try {
6464
result = this[fn].call(this, ...args);
65-
if (result instanceof Float32Array) {
66-
//transferables.push(result);
65+
if (result && result.length) {
66+
for (let i = 0; i < result.length; ++i) {
67+
const o = result[i];
68+
if (o instanceof Float32Array) {
69+
transferables.push(o);
70+
}
71+
}
6772
}
6873
} catch (e) {
6974
error = e;
@@ -166,14 +171,14 @@ class BeatWorkletProcessor extends AudioWorkletProcessor {
166171
this.#deregisterObj(id);
167172
}
168173
169-
getSamplesForTimeRange(start, end, step, contextId, stackId, channel = 0) {
174+
getSamplesForTimeRange(start, end, numSamples, contextId, stackId, channel = 0) {
170175
const context = this.idToObj.get(contextId);
171176
const stack = this.idToObj.get(stackId);
172-
const len = Math.ceil((end - start) / step);
173-
const data = new Float32Array(len);
174-
let cursor = 0;
175-
for (let time = start; time < end; time += step) {
176-
data[cursor++] = this.byteBeat.getSampleForTime(time, context, stack, channel);
177+
const data = new Float32Array(numSamples);
178+
const duration = end - start;
179+
for (let i = 0; i < numSamples; ++i) {
180+
const time = start + duration * i / numSamples | 0;
181+
data[i] = this.byteBeat.getSampleForTime(time, context, stack, channel);
177182
}
178183
return data;
179184
}

0 commit comments

Comments
 (0)