@webaudiomodules/sdk
Version:
WebAudioModules Plugin SDK
283 lines (241 loc) • 7.52 kB
text/typescript
/* eslint-disable no-underscore-dangle */
/* eslint-disable no-plusplus */
import expect from './jestUtilities';
import { shuffleArray, ensureTextEncoderDecoder } from './testUtilities';
import {
WamEvent, WamAutomationEvent, WamTransportEvent,
WamMidiEvent, WamMpeEvent, WamSysexEvent, WamOscEvent, WamInfoEvent
} from '@webaudiomodules/api';
import getRingBuffer from '../src/RingBuffer.js';
import getWamEventRingBuffer from '../src/WamEventRingBuffer.js';
const RingBuffer = getRingBuffer();
const WamEventRingBuffer = getWamEventRingBuffer();
ensureTextEncoderDecoder(); // jest / JSDOM doesn't currently have these globals
describe('WamEventRingBuffer Suite', () => {
const binaryBytesLength = 72;
const parameterIds = ['x', 'y', 'z'];
const inputAutomationEvent: WamAutomationEvent = {
type: 'wam-automation',
time: 10 * Math.random(),
data: {
id: 'y',
value: Math.random(),
normalized: true,
},
};
const inputTransportEvent: WamTransportEvent = {
type: 'wam-transport',
time: 10 * Math.random(),
data: {
currentBar: Math.round(10 * Math.random()),
currentBarStarted: 10 * Math.random(),
tempo: 120,
timeSigNumerator: 3,
timeSigDenominator: 4,
playing: true,
},
};
const inputMidiEvent: WamMidiEvent = {
type: 'wam-midi',
time: 10 * Math.random(),
data: {
bytes: [0x80, 0x80, 0x80],
},
};
const inputMpeEvent: WamMpeEvent = {
type: 'wam-mpe',
time: 10 * Math.random(),
data: {
bytes: [0x90, 0x90, 0x90],
},
};
const sysexBytes = new Uint8Array(binaryBytesLength);
let b = 0;
while (b < binaryBytesLength) {
sysexBytes[b] = Math.random() * 256;
b++;
}
const inputSysexEvent: WamSysexEvent = {
type: 'wam-sysex',
time: 10 * Math.random(),
data: {
bytes: sysexBytes,
},
};
const oscBytes = new Uint8Array(binaryBytesLength);
b = 0;
while (b < binaryBytesLength) {
oscBytes[b] = Math.random() * 256;
b++;
}
const inputOscEvent: WamOscEvent = {
type: 'wam-osc',
time: 10 * Math.random(),
data: {
bytes: sysexBytes,
},
};
const inputInfoEvent: WamInfoEvent = {
type: 'wam-info',
time: 10 * Math.random(),
data: {
instanceId: `some-wam-name.instance.${Date.now().toString()}`,
}
}
it('Should handle updating parameter ids', () => {
const xAutomationEvent: WamAutomationEvent = {
type: 'wam-automation',
time: 10 * Math.random(),
data: {
id: 'x',
value: Math.random(),
normalized: true,
},
};
const yAutomationEvent = inputAutomationEvent;
const zAutomationEvent: WamAutomationEvent = {
type: 'wam-automation',
time: 10 * Math.random(),
data: {
id: 'z',
value: Math.random(),
normalized: true,
},
};
const aAutomationEvent: WamAutomationEvent = {
type: 'wam-automation',
time: 10 * Math.random(),
data: {
id: 'a',
value: Math.random(),
normalized: true,
},
};
const bAutomationEvent: WamAutomationEvent = {
type: 'wam-automation',
time: 10 * Math.random(),
data: {
id: 'b',
value: Math.random(),
normalized: true,
},
};
const inputEvents = [
xAutomationEvent,
yAutomationEvent,
zAutomationEvent,
aAutomationEvent,
bAutomationEvent,
];
const sab = WamEventRingBuffer.getStorageForEventCapacity(RingBuffer, inputEvents.length);
const test = new WamEventRingBuffer(RingBuffer, sab, parameterIds, binaryBytesLength);
let numWritten = test.write(...inputEvents);
expect(numWritten).toEqual(inputEvents.length - 2);
let expectedOutputEvents = [
xAutomationEvent,
yAutomationEvent,
zAutomationEvent,
];
let outputEvents = test.read();
let numRead = outputEvents.length;
expect(numRead).toEqual(numWritten);
expect(outputEvents).toEqual(expectedOutputEvents);
const newParameterIds = ['a', 'b', 'y', 'z'];
test.setParameterIds(newParameterIds);
numWritten = test.write(...inputEvents);
expect(numWritten).toEqual(inputEvents.length - 1);
expectedOutputEvents = [
yAutomationEvent,
zAutomationEvent,
aAutomationEvent,
bAutomationEvent,
];
outputEvents = test.read();
numRead = outputEvents.length;
expect(numRead).toEqual(numWritten);
expect(outputEvents).toEqual(expectedOutputEvents);
test.setParameterIds(parameterIds);
numWritten = test.write(...inputEvents);
expect(numWritten).toEqual(inputEvents.length - 2);
test.setParameterIds(newParameterIds);
expectedOutputEvents = [
yAutomationEvent,
zAutomationEvent,
];
outputEvents = test.read();
numRead = outputEvents.length;
expect(numRead).toEqual(numWritten - 1);
expect(outputEvents).toEqual(expectedOutputEvents);
});
it('Should allocate enough bytes for events of all types', () => {
const defaultSab = WamEventRingBuffer.getStorageForEventCapacity(RingBuffer, 1);
expect(defaultSab.byteLength).toBeGreaterThan(WamEventRingBuffer.WamEventBaseBytes);
expect(defaultSab.byteLength).toBeGreaterThan(WamEventRingBuffer.WamAutomationEventBytes);
expect(defaultSab.byteLength).toBeGreaterThan(WamEventRingBuffer.WamTransportEventBytes);
expect(defaultSab.byteLength).toBeGreaterThan(WamEventRingBuffer.WamMidiEventBytes);
const binarySab = WamEventRingBuffer.getStorageForEventCapacity(RingBuffer, 1,
binaryBytesLength);
expect(binarySab.byteLength).toBeGreaterThan(WamEventRingBuffer.WamBinaryEventBytes
+ binaryBytesLength);
const testNumEvents = 333;
const testSab = WamEventRingBuffer.getStorageForEventCapacity(RingBuffer, testNumEvents);
expect(testSab.byteLength).toBeGreaterThan(WamEventRingBuffer.WamTransportEventBytes
* testNumEvents);
});
it('Should only write number of events for which there is enough space', () => {
const inputEvents = [
inputSysexEvent,
inputSysexEvent,
];
const sab = WamEventRingBuffer.getStorageForEventCapacity(RingBuffer, 1);
const test = new WamEventRingBuffer(RingBuffer, sab, parameterIds, binaryBytesLength);
const numWritten = test.write(...inputEvents);
expect(numWritten).toEqual(1);
});
it('Should read and write individual events of all types', () => {
const inputEvents = [
inputAutomationEvent,
inputTransportEvent,
inputMidiEvent,
inputMpeEvent,
inputSysexEvent,
inputOscEvent,
inputInfoEvent,
];
let written = 0;
let read: WamEvent[] = [];
const sab = WamEventRingBuffer.getStorageForEventCapacity(RingBuffer, 1, binaryBytesLength);
const test = new WamEventRingBuffer(RingBuffer, sab, parameterIds, binaryBytesLength);
inputEvents.forEach((inputEvent) => {
written = test.write(inputEvent);
expect(written).toEqual(1);
read = test.read();
expect(read.length).toEqual(1);
const outputEvent = read[0];
expect(inputEvent).toEqual(outputEvent);
});
});
it('Should read and write multiple events of all types', () => {
const inputEvents = [
inputAutomationEvent,
inputTransportEvent,
inputMidiEvent,
inputMpeEvent,
inputSysexEvent,
inputOscEvent,
inputInfoEvent,
];
const numEvents = inputEvents.length;
shuffleArray(inputEvents);
const sab = WamEventRingBuffer.getStorageForEventCapacity(RingBuffer,
numEvents, binaryBytesLength);
const test = new WamEventRingBuffer(RingBuffer, sab, parameterIds, binaryBytesLength);
test.write(...inputEvents);
const outputEvents = test.read();
expect(outputEvents.length).toEqual(inputEvents.length);
inputEvents.forEach((inputEvent, i) => {
const outputEvent = outputEvents[i];
expect(inputEvent).toEqual(outputEvent);
});
});
});