Skip to content

Instantly share code, notes, and snippets.

@jinjor
Created June 4, 2019 19:21
Show Gist options
  • Save jinjor/c989ac523b0fd3c88e5ece5c8e3a8eb6 to your computer and use it in GitHub Desktop.
Save jinjor/c989ac523b0fd3c88e5ece5c8e3a8eb6 to your computer and use it in GitHub Desktop.
interface State {
index: number;
name: string;
createdAt: number;
startedAt: number;
stoppedAt: number;
connectedAt: number;
disconnectedAt: number;
}
const nodes = new WeakMap<AudioNode, State>();
const states = new Array<State>();
const DEBUG = false;
export function unwrapContext(audioContext: AudioContext): AudioContext {
if (!DEBUG) {
return audioContext;
}
return (audioContext as any).unsafeUnwrap || audioContext;
}
export function unwrapNode(audioNode: AudioNode): AudioNode {
if (!DEBUG) {
return audioNode;
}
return (audioNode as any).unsafeUnwrap || audioNode;
}
export function proxyContext(audioContext: AudioContext): AudioContext {
if (!DEBUG) {
return audioContext;
}
return new Proxy<AudioContext>(audioContext, {
get: function(target: AudioContext, property: string) {
if (property === "unsafeUnwrap") {
return target;
}
var value = (target as any)[property];
if (typeof value !== "function") {
return value;
}
return function(...args: any[]) {
if (!property.startsWith("create")) {
return Reflect.apply(value, target, args);
}
const state: State = {
index: states.length,
name: property.slice(6),
createdAt: target.currentTime,
startedAt: null,
stoppedAt: null,
connectedAt: null,
disconnectedAt: null
};
const node = Reflect.apply(value, target, args);
nodes.set(node, state);
states.push(state);
return proxyNode(node);
};
}
});
}
function proxyNode(node: AudioNode): AudioNode {
return new Proxy<AudioNode>(node, {
get: function(target: AudioNode, property: string) {
if (property === "unsafeUnwrap") {
return target;
}
var value = (target as any)[property];
if (typeof value !== "function") {
return value;
}
return function(...args: any[]) {
if (property === "start") {
nodes.get(target).startedAt = args[0] || target.context.currentTime;
}
if (property === "stop") {
nodes.get(target).stoppedAt = args[0] || target.context.currentTime;
}
if (property === "connect") {
nodes.get(target).connectedAt = target.context.currentTime;
args = args.map(unwrapNode);
}
if (property === "disconnect") {
nodes.get(target).disconnectedAt = target.context.currentTime;
args = args.map(unwrapNode);
}
return Reflect.apply(value, target, args);
};
},
set: function(target: AudioNode, property: string, value: any) {
return ((target as any)[property] = value);
}
});
}
if (DEBUG) {
(window as any).states = states;
(window as any).showState = () => {
states
.map(
(s, i) =>
` ${i}`.slice(-5) +
":" +
`${s.createdAt}`.slice(-5) +
" " +
s.name.slice(0, 4) +
" " +
(s.connectedAt ? "[" : " ") +
" " +
(s.startedAt ? "<" : " ") +
" " +
(s.stoppedAt ? ">" : " ") +
" " +
(s.disconnectedAt ? "]" : " ")
)
.forEach(s => console.log(s));
};
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment