@ekx/auph
Version:
[](https://github.com/eliasku/auph/actions/workflows/build.yml) [](https://www.npmjs.com/package/auph) [ {
var ctx = initContext();
if (ctx) {
initBusPool(ctx);
}
}
export function shutdown() {
var ctx = getContext();
if (ctx) {
termBusPool();
resize(voicePool, 1);
resize(buffers, 1);
closeContext(ctx);
}
}
export function load(filepath, flags) {
var handle = getNextBufferObj();
if (handle) {
var ctx = getAudioContextObject();
if (!ctx) {
setError(24 /* NotInitialized */);
return 0;
}
var obj = buffers[handle & iMask];
_bufferLoad(obj, ctx, filepath, flags);
}
return handle;
}
export function loadMemory(data, flags) {
var handle = getNextBufferObj();
if (handle) {
var ctx = getAudioContextObject();
if (!ctx) {
setError(24 /* NotInitialized */);
return 0;
}
var obj = buffers[handle & iMask];
_bufferMemory(obj, ctx, data, flags);
}
return handle;
}
export function load_callback(p_callback, p_userdata) {
var handle = getNextBufferObj();
if (handle) {
var ctx = getAudioContextObject();
if (!ctx) {
setError(24 /* NotInitialized */);
return 0;
}
var obj = buffers[handle & iMask];
_buffer_set_callback(obj, ctx, p_callback, p_userdata);
}
return handle;
}
export function unload(name) {
var obj = _getBufferObj(name);
if (obj) {
stop(name);
_bufferDestroy(obj);
}
}
/***
*
* @param buffer
* @param gain
* @param pan
* @param rate
* @param flags
* @param bus
*/
export function voice(buffer, gain, pan, rate, flags, bus) {
// arguments check debug
if (flags & ~(2 /* Running */ | 4 /* Loop */)) {
setError(22 /* InvalidArguments */);
return 0;
}
///
var ctx = getAudioContextObject();
if (!ctx || ctx.state !== "running") {
setError(23 /* InvalidMixerState */, ctx === null || ctx === void 0 ? void 0 : ctx.state);
return 0;
}
var bufferObj = _getBufferObj(buffer);
if (!bufferObj) {
setError(15 /* BufferNotFound */);
return 0;
}
if (!(bufferObj.s & 2 /* Loaded */)) {
setError(16 /* BufferIsNotLoaded */);
return 0;
}
if (!bufferObj.b) {
setError(17 /* BufferNoData */);
return 0;
}
var targetNode = _getBusGain(bus ? bus : DefaultBus);
if (!targetNode) {
setError(21 /* BusNotFound */);
return 0;
}
var voice = createVoiceObj(ctx);
if (voice === 0) {
setError(12 /* Warning_NoFreeVoices */);
return 0;
}
var voiceObj = _getVoiceObj(voice);
voiceObj.s = 1 /* Active */ | flags;
voiceObj.bf = buffer;
voiceObj.G = gain;
voiceObj.P = pan;
voiceObj.R = rate;
setAudioParamValue(voiceObj.g.gain, gain / Unit);
setAudioParamValue(voiceObj.p.pan, pan / Unit - 1);
// TODO: streamed decoding
//if (bufferObj.s & Flag.Stream) {
if (bufferObj.s & 16 /* Callback */) {
// const _play_next_chunk = () => {
// _voicePrepareBuffer(voiceObj, ctx, bufferObj.b as AudioBuffer);
// voiceObj.sn!.loop = false;
// const ptr = _auph_read_to_buffer(bufferObj._u, bufferObj._f);
// (bufferObj.b as AudioBuffer).copyToChannel(HEAPF32.subarray(ptr >>> 2, 8192 + (ptr >>> 2)), 0, 0);
// (bufferObj.b as AudioBuffer).copyToChannel(HEAPF32.subarray(8192 + (ptr >>> 2), (2 * 8192) + (ptr >>> 2)), 1, 0);
// voiceObj.sn!.onended = _play_next_chunk;
// voiceObj.sn!.start();
// };
// _play_next_chunk();
//_voicePrepareBuffer(voiceObj, ctx, bufferObj.b as AudioBuffer);
if (flags & 2 /* Running */) {
// _voiceStartBuffer(voiceObj);
voiceObj._s = 1;
//voiceObj.sn!.loop = true;
var processor = ctx.createScriptProcessor(8192, 0, 2);
processor.onaudioprocess = function (ev) {
// The output buffer contains the samples that will be modified and played
var outputBuffer = ev.outputBuffer;
// Loop through the output channels (in this case there is only one)
var ptr = _auph_read_to_buffer(bufferObj._u, bufferObj._f);
var output0 = outputBuffer.getChannelData(0);
var output1 = outputBuffer.getChannelData(1);
output0.set(HEAPF32.subarray(ptr >>> 2, 8192 + (ptr >>> 2)));
output1.set(HEAPF32.subarray(8192 + (ptr >>> 2), (2 * 8192) + (ptr >>> 2)));
};
//disconnectAudioNode(voiceObj.sn!, voiceObj.p);
// connectAudioNode(voiceObj.sn!, processor);
connectAudioNode(processor, voiceObj.p);
//voiceObj.sn!.start();
voiceObj.pr = processor;
}
}
else {
_voicePrepareBuffer(voiceObj, ctx, bufferObj.b);
if (flags & 2 /* Running */) {
_voiceStartBuffer(voiceObj);
}
}
// maybe we need to set target before `startBuffer()`
_voiceChangeDestination(voiceObj, targetNode);
_voiceApplyPitch(voiceObj, rate);
return voice;
}
export function stop(name) {
if (name === 0) {
return;
}
var type = name & tMask;
if (type === 805306368 /* Voice */) {
var obj = _getVoiceObj(name);
if (obj) {
_voiceStop(obj);
}
}
else if (type === 536870912 /* Buffer */) {
var obj = _getBufferObj(name);
if (obj) {
for (var i = 1; i < len(voicePool); ++i) {
var v = voicePool[i];
if (v.bf === name) {
_voiceStop(v);
}
}
}
else {
setError(15 /* BufferNotFound */);
}
}
}
export function set(name, param, value) {
if (name === 0) {
return;
}
if (name === Mixer && (param & 128 /* Flags */) && (param & 2 /* Running */)) {
var ctx = getContext();
if (ctx) {
if (value && ctx.state === "suspended") {
audioContextResume(ctx);
}
else if (!value && ctx.state === "running") {
audioContextPause(ctx);
}
}
}
var type = name & tMask;
if (type === 805306368 /* Voice */) {
var obj = _getVoiceObj(name);
if (obj) {
if (param & 128 /* Flags */) {
var enabled = value !== 0;
if (param & 2 /* Running */) {
_voiceSetRunning(obj, enabled);
}
else if (param & 4 /* Loop */) {
_voiceSetLoop(obj, enabled);
}
}
else {
if (param === 1 /* Gain */) {
if (obj.G !== value) {
obj.G = value;
setAudioParamValue(obj.g.gain, value / Unit);
}
}
else if (param === 2 /* Pan */) {
if (obj.P !== value) {
obj.P = value;
setAudioParamValue(obj.p.pan, value / Unit - 1);
}
}
else if (param === 3 /* Rate */) {
if (obj.R !== value) {
obj.R = value;
_voiceApplyPitch(obj, value);
}
}
else if (param === 4 /* CurrentTime */) {
// TODO:
}
}
}
}
else if (type === 268435456 /* Bus */) {
var obj = _getBus(name);
if (obj) {
if (param & 128 /* Flags */) {
if (param & 2 /* Running */) {
_setBusConnected(obj, !!value);
}
}
else {
if (param === 1 /* Gain */) {
if (obj.G !== value) {
setAudioParamValue(obj.g.gain, value / Unit);
obj.G = value;
}
}
else {
}
}
}
}
}
export function get(name, param) {
var result = 0;
if (name === Mixer) {
var ctx = getAudioContextObject();
if (ctx) {
if (param === 0 /* State */) {
result = getContextState(ctx);
}
else if (param === 5 /* SampleRate */) {
result = ctx.sampleRate | 0;
}
}
return result;
}
var type = name & tMask;
if ((param & 256 /* Count */) && !(name & iMask)) {
var stateMask = param & 127 /* StateMask */;
if (type === 805306368 /* Voice */) {
result = _countObjectsWithFlags(voicePool, stateMask);
}
else if (type === 268435456 /* Bus */) {
result = _countObjectsWithFlags(busLine, stateMask);
}
else if (type === 536870912 /* Buffer */) {
result = _countObjectsWithFlags(buffers, stateMask);
}
return result;
}
if (type === 805306368 /* Voice */) {
var obj = _getVoiceObj(name);
if (obj) {
if (param === 0 /* State */) {
result = obj.s;
}
else if (param === 1 /* Gain */) {
result = obj.G;
}
else if (param === 2 /* Pan */) {
result = obj.P;
}
else if (param === 3 /* Rate */) {
result = obj.R;
}
else if (param === 6 /* Duration */) {
if (obj.sn && obj.sn.buffer) {
result = (obj.sn.buffer.duration * Unit) | 0;
}
}
else if (param === 4 /* CurrentTime */) {
if (obj.sn && obj.sn.buffer) {
// TODO: :(
}
}
else {
warn(1 /* NotSupported */);
}
}
return result;
}
if (type === 268435456 /* Bus */) {
var obj = _getBus(name);
if (obj) {
if (param === 0 /* State */) {
result = obj.s;
}
else if (param === 1 /* Gain */) {
result = obj.G;
}
else {
warn(1 /* NotSupported */);
}
}
return result;
}
if (type === 536870912 /* Buffer */) {
var obj = _getBufferObj(name);
if (obj) {
if (param === 0 /* State */) {
result = obj.s;
}
else if (param === 6 /* Duration */) {
if (obj.b) {
result = (obj.b.duration * Unit) | 0;
}
}
else {
warn(1 /* NotSupported */);
}
}
}
return result;
}
export function vibrate(durationMillis) {
try {
if (navigator.vibrate) {
return navigator.vibrate(durationMillis) ? 0 : 1;
}
}
catch (_a) {
}
return 1;
}
/** private helpers **/
function _countObjectsWithFlags(arr, mask) {
var cnt = 0;
var size = len(arr);
for (var i = 1; i < size; ++i) {
var obj = arr[i];
if (obj && (obj.s & mask) === mask) {
++cnt;
}
}
return cnt;
}
//# sourceMappingURL=index.js.map