basic scope feature
This commit is contained in:
parent
f20c5a1bcb
commit
7370f41fa0
5 changed files with 91 additions and 2 deletions
|
|
@ -146,6 +146,9 @@ const generic_params = [
|
|||
*/
|
||||
['bank'],
|
||||
|
||||
['analyze'], // sends
|
||||
['fft'],
|
||||
|
||||
/**
|
||||
* Amplitude envelope decay time: the time it takes after the attack time to reach the sustain level.
|
||||
* Note that the decay is only audible if the sustain value is lower than 1.
|
||||
|
|
|
|||
|
|
@ -27,7 +27,7 @@ export const getDrawContext = (id = 'test-canvas') => {
|
|||
return canvas.getContext('2d');
|
||||
};
|
||||
|
||||
Pattern.prototype.draw = function (callback, { from, to, onQuery }) {
|
||||
Pattern.prototype.draw = function (callback, { from, to, onQuery } = {}) {
|
||||
if (window.strudelAnimation) {
|
||||
cancelAnimationFrame(window.strudelAnimation);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -22,6 +22,7 @@ export * from './cyclist.mjs';
|
|||
export * from './logger.mjs';
|
||||
export * from './time.mjs';
|
||||
export * from './draw.mjs';
|
||||
export * from './scope.mjs';
|
||||
export * from './animate.mjs';
|
||||
export * from './pianoroll.mjs';
|
||||
export * from './spiral.mjs';
|
||||
|
|
|
|||
48
packages/core/scope.mjs
Normal file
48
packages/core/scope.mjs
Normal file
|
|
@ -0,0 +1,48 @@
|
|||
import { Pattern } from './pattern.mjs';
|
||||
import { getDrawContext } from './draw.mjs';
|
||||
import { analyser } from '@strudel.cycles/webaudio';
|
||||
|
||||
export function drawTimeScope(analyser, dataArray, { align = true, color = 'white', thickness = 2 } = {}) {
|
||||
const canvasCtx = getDrawContext();
|
||||
|
||||
canvasCtx.lineWidth = thickness;
|
||||
canvasCtx.strokeStyle = color;
|
||||
|
||||
canvasCtx.beginPath();
|
||||
let canvas = canvasCtx.canvas;
|
||||
|
||||
const bufferSize = analyser.frequencyBinCount;
|
||||
const triggerValue = 256 / 2;
|
||||
const triggerIndex = align
|
||||
? Array.from(dataArray).findIndex((v, i, arr) => i && arr[i - 1] < triggerValue && v >= triggerValue)
|
||||
: 0;
|
||||
|
||||
const sliceWidth = (canvas.width * 1.0) / bufferSize;
|
||||
let x = 0;
|
||||
|
||||
for (let i = triggerIndex; i < bufferSize; i++) {
|
||||
const v = dataArray[i] / 128.0;
|
||||
const y = (v * (canvas.height / 2)) / 2 + canvas.height / 2;
|
||||
if (i === 0) {
|
||||
canvasCtx.moveTo(x, y);
|
||||
} else {
|
||||
canvasCtx.lineTo(x, y);
|
||||
}
|
||||
x += sliceWidth;
|
||||
}
|
||||
canvasCtx.stroke();
|
||||
}
|
||||
|
||||
Pattern.prototype.scope = function (config = {}) {
|
||||
return this.analyze(1).draw((ctx) => {
|
||||
let data = getAnalyzerData('time');
|
||||
const { smear = 0 } = config;
|
||||
if (!smear) {
|
||||
ctx.clearRect(0, 0, window.innerWidth, window.innerHeight);
|
||||
} else {
|
||||
ctx.fillStyle = `rgba(0,0,0,${1 - smear})`;
|
||||
ctx.fillRect(0, 0, window.innerWidth, window.innerHeight);
|
||||
}
|
||||
data && drawTimeScope(analyser, data, config);
|
||||
});
|
||||
};
|
||||
Loading…
Add table
Add a link
Reference in a new issue