databender 2.0.0-alpha.0 → 2.0.0-alpha.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +20 -0
- package/dist/databender.js +52 -0
- package/index.js +52 -0
- package/package.json +1 -1
- package/tags +16 -3
package/README.md
CHANGED
|
@@ -158,6 +158,26 @@ databender.bend(img, context);
|
|
|
158
158
|
|
|
159
159
|
Because Databender spins up a brand new `OfflineAudioContext` for every render, the worklet module has to be registered on that context before the node is created. Returning a promise from your effect factory ensures the render waits for the module to load.
|
|
160
160
|
|
|
161
|
+
### Source parameters
|
|
162
|
+
|
|
163
|
+
Some tweaks (e.g. `detune` or `playbackRate`) must be applied directly to the `AudioBufferSourceNode` **before** it starts. Pass functions to `sourceParams` and they'll run prior to chaining any effects. Each factory receives the same payload (`{ context, source, config }`) as the regular effect chain.
|
|
164
|
+
|
|
165
|
+
```js
|
|
166
|
+
const databender = new Databender({
|
|
167
|
+
config,
|
|
168
|
+
sourceParams: [
|
|
169
|
+
({ source, config }) => {
|
|
170
|
+
const value = config?.detune?.value ?? 0;
|
|
171
|
+
source.detune.value = value;
|
|
172
|
+
}
|
|
173
|
+
],
|
|
174
|
+
effectsChain: [
|
|
175
|
+
useDelayEffect(),
|
|
176
|
+
useBitcrusher()
|
|
177
|
+
]
|
|
178
|
+
});
|
|
179
|
+
```
|
|
180
|
+
|
|
161
181
|
### Prerequisites
|
|
162
182
|
|
|
163
183
|
Google Chrome (ideally) and an open mind!
|
package/dist/databender.js
CHANGED
|
@@ -35,6 +35,7 @@ var Databender = (function () {
|
|
|
35
35
|
config = {},
|
|
36
36
|
effectsChain = null,
|
|
37
37
|
chainMode = 'series',
|
|
38
|
+
sourceParams = null,
|
|
38
39
|
audioCtx = null
|
|
39
40
|
} = {}) {
|
|
40
41
|
this.audioCtx = audioCtx ? audioCtx : new AudioContext();
|
|
@@ -43,7 +44,11 @@ var Databender = (function () {
|
|
|
43
44
|
this.configKeys = Object.keys(this.config);
|
|
44
45
|
this.previousConfig = this.config;
|
|
45
46
|
this.effectsChain = effectsChain ? asArray(effectsChain) : null;
|
|
47
|
+
this.sourceParams = sourceParams ? asArray(sourceParams) : null;
|
|
46
48
|
this.chainMode = chainMode === 'parallel' ? 'parallel' : 'series';
|
|
49
|
+
this.maxConcurrentRenders = 2;
|
|
50
|
+
this.activeRenderCount = 0;
|
|
51
|
+
this.renderQueue = [];
|
|
47
52
|
|
|
48
53
|
this.convert = function(image) {
|
|
49
54
|
if (image instanceof Image || image instanceof HTMLVideoElement) {
|
|
@@ -90,6 +95,27 @@ var Databender = (function () {
|
|
|
90
95
|
};
|
|
91
96
|
|
|
92
97
|
this.render = async function(buffer, bypass = false) {
|
|
98
|
+
const acquireRenderSlot = async () => {
|
|
99
|
+
if (this.activeRenderCount < this.maxConcurrentRenders) {
|
|
100
|
+
this.activeRenderCount += 1;
|
|
101
|
+
return;
|
|
102
|
+
}
|
|
103
|
+
await new Promise((resolve) => {
|
|
104
|
+
this.renderQueue.push({ resolve });
|
|
105
|
+
});
|
|
106
|
+
this.activeRenderCount += 1;
|
|
107
|
+
};
|
|
108
|
+
|
|
109
|
+
const releaseRenderSlot = () => {
|
|
110
|
+
this.activeRenderCount = Math.max(0, this.activeRenderCount - 1);
|
|
111
|
+
const next = this.renderQueue.shift();
|
|
112
|
+
if (next && isFunction(next.resolve)) {
|
|
113
|
+
next.resolve();
|
|
114
|
+
}
|
|
115
|
+
};
|
|
116
|
+
|
|
117
|
+
await acquireRenderSlot();
|
|
118
|
+
try {
|
|
93
119
|
|
|
94
120
|
// Create offlineAudioCtx that will house our rendered buffer
|
|
95
121
|
var offlineAudioCtx = new OfflineAudioContext(this.channels, buffer.length * this.channels, this.audioCtx.sampleRate);
|
|
@@ -141,6 +167,29 @@ var Databender = (function () {
|
|
|
141
167
|
return resolvedNodes;
|
|
142
168
|
}.bind(this);
|
|
143
169
|
|
|
170
|
+
var applySourceParams = async function() {
|
|
171
|
+
if (bypass || !this.sourceParams) {
|
|
172
|
+
return;
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
var candidates = asArray(this.sourceParams);
|
|
176
|
+
|
|
177
|
+
for (var i = 0; i < candidates.length; i++) {
|
|
178
|
+
var candidate = candidates[i];
|
|
179
|
+
var result = candidate;
|
|
180
|
+
|
|
181
|
+
if (isFunction(result)) {
|
|
182
|
+
result = result({ context: offlineAudioCtx, source: bufferSource, config: this.config });
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
if (isPromise(result)) {
|
|
186
|
+
await result;
|
|
187
|
+
}
|
|
188
|
+
}
|
|
189
|
+
}.bind(this);
|
|
190
|
+
|
|
191
|
+
await applySourceParams();
|
|
192
|
+
|
|
144
193
|
var effectNodes = (await resolveEffectsChain()).map(normalizeEffectNode).filter(Boolean);
|
|
145
194
|
|
|
146
195
|
if (!effectNodes.length) {
|
|
@@ -164,6 +213,9 @@ var Databender = (function () {
|
|
|
164
213
|
this.previousConfig = this.config;
|
|
165
214
|
// Kick off the render, callback will contain rendered buffer in event
|
|
166
215
|
return offlineAudioCtx.startRendering();
|
|
216
|
+
} finally {
|
|
217
|
+
releaseRenderSlot();
|
|
218
|
+
}
|
|
167
219
|
};
|
|
168
220
|
|
|
169
221
|
this.draw = function(buffer, context, sourceX = 0, sourceY = 0, x = 0, y = 0, sourceWidth = this.imageData.width, sourceHeight = this.imageData.height, targetWidth = window.innerWidth, targetHeight = window.innerHeight) {
|
package/index.js
CHANGED
|
@@ -33,6 +33,7 @@ export default class Databender {
|
|
|
33
33
|
config = {},
|
|
34
34
|
effectsChain = null,
|
|
35
35
|
chainMode = 'series',
|
|
36
|
+
sourceParams = null,
|
|
36
37
|
audioCtx = null
|
|
37
38
|
} = {}) {
|
|
38
39
|
this.audioCtx = audioCtx ? audioCtx : new AudioContext();
|
|
@@ -41,7 +42,11 @@ export default class Databender {
|
|
|
41
42
|
this.configKeys = Object.keys(this.config);
|
|
42
43
|
this.previousConfig = this.config;
|
|
43
44
|
this.effectsChain = effectsChain ? asArray(effectsChain) : null;
|
|
45
|
+
this.sourceParams = sourceParams ? asArray(sourceParams) : null;
|
|
44
46
|
this.chainMode = chainMode === 'parallel' ? 'parallel' : 'series';
|
|
47
|
+
this.maxConcurrentRenders = 2;
|
|
48
|
+
this.activeRenderCount = 0;
|
|
49
|
+
this.renderQueue = [];
|
|
45
50
|
|
|
46
51
|
this.convert = function(image) {
|
|
47
52
|
if (image instanceof Image || image instanceof HTMLVideoElement) {
|
|
@@ -88,6 +93,27 @@ export default class Databender {
|
|
|
88
93
|
};
|
|
89
94
|
|
|
90
95
|
this.render = async function(buffer, bypass = false) {
|
|
96
|
+
const acquireRenderSlot = async () => {
|
|
97
|
+
if (this.activeRenderCount < this.maxConcurrentRenders) {
|
|
98
|
+
this.activeRenderCount += 1;
|
|
99
|
+
return;
|
|
100
|
+
}
|
|
101
|
+
await new Promise((resolve) => {
|
|
102
|
+
this.renderQueue.push({ resolve });
|
|
103
|
+
});
|
|
104
|
+
this.activeRenderCount += 1;
|
|
105
|
+
};
|
|
106
|
+
|
|
107
|
+
const releaseRenderSlot = () => {
|
|
108
|
+
this.activeRenderCount = Math.max(0, this.activeRenderCount - 1);
|
|
109
|
+
const next = this.renderQueue.shift();
|
|
110
|
+
if (next && isFunction(next.resolve)) {
|
|
111
|
+
next.resolve();
|
|
112
|
+
}
|
|
113
|
+
};
|
|
114
|
+
|
|
115
|
+
await acquireRenderSlot();
|
|
116
|
+
try {
|
|
91
117
|
|
|
92
118
|
// Create offlineAudioCtx that will house our rendered buffer
|
|
93
119
|
var offlineAudioCtx = new OfflineAudioContext(this.channels, buffer.length * this.channels, this.audioCtx.sampleRate);
|
|
@@ -139,6 +165,29 @@ export default class Databender {
|
|
|
139
165
|
return resolvedNodes;
|
|
140
166
|
}.bind(this);
|
|
141
167
|
|
|
168
|
+
var applySourceParams = async function() {
|
|
169
|
+
if (bypass || !this.sourceParams) {
|
|
170
|
+
return;
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
var candidates = asArray(this.sourceParams);
|
|
174
|
+
|
|
175
|
+
for (var i = 0; i < candidates.length; i++) {
|
|
176
|
+
var candidate = candidates[i];
|
|
177
|
+
var result = candidate;
|
|
178
|
+
|
|
179
|
+
if (isFunction(result)) {
|
|
180
|
+
result = result({ context: offlineAudioCtx, source: bufferSource, config: this.config });
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
if (isPromise(result)) {
|
|
184
|
+
await result;
|
|
185
|
+
}
|
|
186
|
+
}
|
|
187
|
+
}.bind(this);
|
|
188
|
+
|
|
189
|
+
await applySourceParams();
|
|
190
|
+
|
|
142
191
|
var effectNodes = (await resolveEffectsChain()).map(normalizeEffectNode).filter(Boolean);
|
|
143
192
|
|
|
144
193
|
if (!effectNodes.length) {
|
|
@@ -162,6 +211,9 @@ export default class Databender {
|
|
|
162
211
|
this.previousConfig = this.config;
|
|
163
212
|
// Kick off the render, callback will contain rendered buffer in event
|
|
164
213
|
return offlineAudioCtx.startRendering();
|
|
214
|
+
} finally {
|
|
215
|
+
releaseRenderSlot();
|
|
216
|
+
}
|
|
165
217
|
};
|
|
166
218
|
|
|
167
219
|
this.draw = function(buffer, context, sourceX = 0, sourceY = 0, x = 0, y = 0, sourceWidth = this.imageData.width, sourceHeight = this.imageData.height, targetWidth = window.innerWidth, targetHeight = window.innerHeight) {
|
package/package.json
CHANGED
package/tags
CHANGED
|
@@ -141,12 +141,17 @@ Examples README.md /^## Examples$/;" s chapter:Databender
|
|
|
141
141
|
Getting Started README.md /^## Getting Started$/;" s chapter:Databender
|
|
142
142
|
License README.md /^## License$/;" s chapter:Databender
|
|
143
143
|
Prerequisites README.md /^### Prerequisites$/;" S section:Databender""Getting Started
|
|
144
|
+
Source parameters README.md /^### Source parameters$/;" S section:Databender""Getting Started
|
|
144
145
|
anonymousObject48d51f9d0205 dist/databender.js /^ constructor({$/;" v class:Databender.Databender
|
|
145
146
|
anonymousObject48d51f9d0905 dist/databender.js /^ resolvedNode = resolvedNode({ context: offlineAudioCtx, source: buff/;" v function:Databender.Databender.constructor.render.resolveEffectsChain
|
|
147
|
+
anonymousObject48d51f9d0b05 dist/databender.js /^ result = result({ context: offlineAudioCtx, source: bufferSource, co/;" v function:Databender.Databender.constructor.render.applySourceParams
|
|
146
148
|
anonymousObject66e3de480105 index.js /^ constructor({$/;" v class:Databender
|
|
147
149
|
anonymousObject66e3de480805 index.js /^ resolvedNode = resolvedNode({ context: offlineAudioCtx, source: bufferSo/;" v function:Databender.constructor.render.resolveEffectsChain
|
|
150
|
+
anonymousObject66e3de480a05 index.js /^ result = result({ context: offlineAudioCtx, source: bufferSource, config/;" v function:Databender.constructor.render.applySourceParams
|
|
148
151
|
anonymousObject6c12f9b20105 rollup.config.js /^ resolve({$/;" v
|
|
149
152
|
anonymousObject6c12f9b20205 rollup.config.js /^ commonjs({$/;" v
|
|
153
|
+
applySourceParams dist/databender.js /^ var applySourceParams = async function() {$/;" f method:Databender.Databender.constructor.render
|
|
154
|
+
applySourceParams index.js /^ var applySourceParams = async function() {$/;" f method:Databender.constructor.render
|
|
150
155
|
asArray dist/databender.js /^ const asArray = (value) => {$/;" f class:Databender
|
|
151
156
|
asArray index.js /^const asArray = (value) => {$/;" f
|
|
152
157
|
audioCtx dist/databender.js /^ audioCtx = null$/;" p variable:Databender.Databender.anonymousObject48d51f9d0205
|
|
@@ -162,15 +167,19 @@ chainMode dist/databender.js /^ chainMode = 'series',$/;" p variable:
|
|
|
162
167
|
chainMode index.js /^ chainMode = 'series',$/;" p variable:Databender.anonymousObject66e3de480105
|
|
163
168
|
commondir package-lock.json /^ "commondir": "^1.0.1",$/;" s object:packages.node_modules/@rollup/plugin-commonjs.dependencies
|
|
164
169
|
config dist/databender.js /^ resolvedNode = resolvedNode({ context: offlineAudioCtx, source: buff/;" p variable:Databender.Databender.constructor.render.resolveEffectsChain.anonymousObject48d51f9d0905
|
|
170
|
+
config dist/databender.js /^ result = result({ context: offlineAudioCtx, source: bufferSource, co/;" p variable:Databender.Databender.constructor.render.applySourceParams.anonymousObject48d51f9d0b05
|
|
165
171
|
config dist/databender.js /^ config = {},$/;" p variable:Databender.Databender.anonymousObject48d51f9d0205
|
|
166
172
|
config index.js /^ resolvedNode = resolvedNode({ context: offlineAudioCtx, source: bufferSo/;" p variable:Databender.constructor.render.resolveEffectsChain.anonymousObject66e3de480805
|
|
173
|
+
config index.js /^ result = result({ context: offlineAudioCtx, source: bufferSource, config/;" p variable:Databender.constructor.render.applySourceParams.anonymousObject66e3de480a05
|
|
167
174
|
config index.js /^ config = {},$/;" p variable:Databender.anonymousObject66e3de480105
|
|
168
175
|
configHasChanged dist/databender.js /^ this.configHasChanged = function() {$/;" m method:Databender.Databender.constructor
|
|
169
176
|
configHasChanged index.js /^ this.configHasChanged = function() {$/;" m method:Databender.constructor
|
|
170
177
|
constructor dist/databender.js /^ constructor({$/;" m class:Databender.Databender
|
|
171
178
|
constructor index.js /^ constructor({$/;" m class:Databender
|
|
172
179
|
context dist/databender.js /^ resolvedNode = resolvedNode({ context: offlineAudioCtx, source: buff/;" p variable:Databender.Databender.constructor.render.resolveEffectsChain.anonymousObject48d51f9d0905
|
|
180
|
+
context dist/databender.js /^ result = result({ context: offlineAudioCtx, source: bufferSource, co/;" p variable:Databender.Databender.constructor.render.applySourceParams.anonymousObject48d51f9d0b05
|
|
173
181
|
context index.js /^ resolvedNode = resolvedNode({ context: offlineAudioCtx, source: bufferSo/;" p variable:Databender.constructor.render.resolveEffectsChain.anonymousObject66e3de480805
|
|
182
|
+
context index.js /^ result = result({ context: offlineAudioCtx, source: bufferSource, config/;" p variable:Databender.constructor.render.applySourceParams.anonymousObject66e3de480a05
|
|
174
183
|
convert dist/databender.js /^ this.convert = function(image) {$/;" m method:Databender.Databender.constructor
|
|
175
184
|
convert index.js /^ this.convert = function(image) {$/;" m method:Databender.constructor
|
|
176
185
|
cpu package-lock.json /^ "cpu": [$/;" a object:packages.node_modules/@rollup/rollup-android-arm-eabi
|
|
@@ -583,7 +592,11 @@ rollup package-lock.json /^ "rollup": {$/;" o object:packages.node_module
|
|
|
583
592
|
rollup package.json /^ "rollup": "4.52.4"$/;" s object:devDependencies
|
|
584
593
|
scripts package.json /^ "scripts": {$/;" o
|
|
585
594
|
source dist/databender.js /^ resolvedNode = resolvedNode({ context: offlineAudioCtx, source: buff/;" p variable:Databender.Databender.constructor.render.resolveEffectsChain.anonymousObject48d51f9d0905
|
|
595
|
+
source dist/databender.js /^ result = result({ context: offlineAudioCtx, source: bufferSource, co/;" p variable:Databender.Databender.constructor.render.applySourceParams.anonymousObject48d51f9d0b05
|
|
586
596
|
source index.js /^ resolvedNode = resolvedNode({ context: offlineAudioCtx, source: bufferSo/;" p variable:Databender.constructor.render.resolveEffectsChain.anonymousObject66e3de480805
|
|
597
|
+
source index.js /^ result = result({ context: offlineAudioCtx, source: bufferSource, config/;" p variable:Databender.constructor.render.applySourceParams.anonymousObject66e3de480a05
|
|
598
|
+
sourceParams dist/databender.js /^ sourceParams = null,$/;" p variable:Databender.Databender.anonymousObject48d51f9d0205
|
|
599
|
+
sourceParams index.js /^ sourceParams = null,$/;" p variable:Databender.anonymousObject66e3de480105
|
|
587
600
|
supports-preserve-symlinks-flag package-lock.json /^ "supports-preserve-symlinks-flag": "^1.0.0"$/;" s object:packages.node_modules/resolve.dependencies
|
|
588
601
|
test package.json /^ "test": "echo \\"Error: no test specified\\" && exit 1"$/;" s object:scripts
|
|
589
602
|
updateConfig dist/databender.js /^ this.updateConfig = function(effect, param, value) {$/;" m method:Databender.Databender.constructor
|
|
@@ -597,7 +610,6 @@ version package-lock.json /^ "version": "0.30.19",$/;" s object:packages.no
|
|
|
597
610
|
version package-lock.json /^ "version": "1.0.0",$/;" s object:packages.node_modules/is-module
|
|
598
611
|
version package-lock.json /^ "version": "1.0.0",$/;" s object:packages.node_modules/supports-preserve-symlinks-flag
|
|
599
612
|
version package-lock.json /^ "version": "1.0.1",$/;" s object:packages.node_modules/commondir
|
|
600
|
-
version package-lock.json /^ "version": "1.0.4",$/;" s object:packages.
|
|
601
613
|
version package-lock.json /^ "version": "1.0.7",$/;" s object:packages.node_modules/path-parse
|
|
602
614
|
version package-lock.json /^ "version": "1.0.8",$/;" s object:packages.node_modules/@types/estree
|
|
603
615
|
version package-lock.json /^ "version": "1.1.2",$/;" s object:packages.node_modules/function-bind
|
|
@@ -606,6 +618,7 @@ version package-lock.json /^ "version": "1.20.2",$/;" s object:packages.nod
|
|
|
606
618
|
version package-lock.json /^ "version": "1.22.10",$/;" s object:packages.node_modules/resolve
|
|
607
619
|
version package-lock.json /^ "version": "1.5.5",$/;" s object:packages.node_modules/@jridgewell/sourcemap-codec
|
|
608
620
|
version package-lock.json /^ "version": "16.0.3",$/;" s object:packages.node_modules/@rollup/plugin-node-resolve
|
|
621
|
+
version package-lock.json /^ "version": "2.0.0-alpha.0",$/;" s object:packages.
|
|
609
622
|
version package-lock.json /^ "version": "2.0.2",$/;" s object:packages.node_modules/@rollup/plugin-commonjs/node_modules/estree-walker
|
|
610
623
|
version package-lock.json /^ "version": "2.0.2",$/;" s object:packages.node_modules/@rollup/pluginutils/node_modules/estree-walker
|
|
611
624
|
version package-lock.json /^ "version": "2.0.2",$/;" s object:packages.node_modules/hasown
|
|
@@ -639,5 +652,5 @@ version package-lock.json /^ "version": "4.52.4",$/;" s object:packages.nod
|
|
|
639
652
|
version package-lock.json /^ "version": "4.52.4",$/;" s object:packages.node_modules/rollup
|
|
640
653
|
version package-lock.json /^ "version": "5.3.0",$/;" s object:packages.node_modules/@rollup/pluginutils
|
|
641
654
|
version package-lock.json /^ "version": "6.5.0",$/;" s object:packages.node_modules/fdir
|
|
642
|
-
version package-lock.json /^ "version": "
|
|
643
|
-
version package.json /^ "version": "
|
|
655
|
+
version package-lock.json /^ "version": "2.0.0-alpha.0",$/;" s
|
|
656
|
+
version package.json /^ "version": "2.0.0-alpha.0",$/;" s
|