Skip to content

Commit 723a023

Browse files
committed
creates time domain events
1 parent 3203abb commit 723a023

File tree

16 files changed

+431
-191
lines changed

16 files changed

+431
-191
lines changed

.eslintrc.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
},
1717
"ignorePatterns": [
1818
"rollup.config.js",
19-
"dist/**/*"
19+
"dist/**/*",
20+
"coverage"
2021
]
2122
}

.gitignore

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,3 @@
11
.DS_Store
2-
node_modules
2+
node_modules
3+
coverage

demo/demo2.html

Lines changed: 126 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,126 @@
1+
<!DOCTYPE html>
2+
<html lang="en">
3+
<head>
4+
<meta charset="UTF-8">
5+
<meta http-equiv="X-UA-Compatible" content="IE=edge">
6+
<meta name="viewport" content="width=device-width, initial-scale=1.0">
7+
<title>Demo 1</title>
8+
</head>
9+
<body>
10+
<canvas></canvas>
11+
<br />
12+
<button>get float frequency data</button>
13+
<button>draw byte frequency data</button>
14+
<button>get float time domain data</button>
15+
<button>draw byte time domain data</button>
16+
<br />
17+
18+
<canvas></canvas>
19+
<pre></pre>
20+
</body>
21+
<script src="../dist/bundle.js"></script>
22+
<script>
23+
(async () => {
24+
const FFT_SIZE = 1024 * 2
25+
const SAMPLE_RATE = 44100
26+
27+
const [canvas, snapshotCanvas] = document.querySelectorAll('canvas')
28+
const context2d = canvas.getContext('2d')
29+
const snapshotContext2d = snapshotCanvas.getContext('2d')
30+
const output = document.querySelector('pre')
31+
32+
const [floatFrequencyButton, byteFrequencyButton, floatTimeDomainButton, byteTimeDomainButton] = document.querySelectorAll('button')
33+
34+
const stream = await navigator.mediaDevices.getUserMedia({
35+
audio: true,
36+
video: false
37+
})
38+
39+
canvas.height = 300
40+
canvas.width = 1024
41+
42+
43+
snapshotCanvas.height = 300
44+
snapshotCanvas.width = 1024
45+
46+
const context = new AudioContext({ sampleRate: SAMPLE_RATE })
47+
48+
const audioSource = context.createMediaStreamSource(stream);
49+
50+
const bottomMargin = 30
51+
const analyserNode = await advancedAnalyserNode.createAdvancedAnalyserNode(context, {
52+
fftSize: FFT_SIZE,
53+
samplesBetweenTransforms: FFT_SIZE,
54+
windowFunction: 'none'
55+
})
56+
57+
const drawFrame = (canvas, context2d, data) => {
58+
context2d.clearRect(0, 0, canvas.width, canvas.height)
59+
context2d.beginPath()
60+
for(let i = 0; i < data.length; i ++) {
61+
if (i === 0) {
62+
context2d.moveTo(canvas.width / data.length * i, canvas.height - bottomMargin - data[i] )
63+
} else {
64+
context2d.lineTo(canvas.width / data.length * i, canvas.height - bottomMargin - data[i] )
65+
}
66+
}
67+
context2d.stroke()
68+
}
69+
analyserNode.addEventListener('bytetimedomaindata', ({ detail }) => {
70+
console.log(detail)
71+
drawFrame(canvas, context2d, detail)
72+
})
73+
audioSource.connect(analyserNode)
74+
75+
floatFrequencyButton.onclick = async () => {
76+
const response = await analyserNode.getFloatFrequencyData()
77+
78+
output.innerHTML =
79+
`
80+
\nFloat Frequency Data
81+
82+
\nSize: ${response.length}
83+
\n${response.toString().replace(/,/g, '\n')}
84+
`
85+
}
86+
87+
byteFrequencyButton.onclick = async () => {
88+
const response = await analyserNode.getByteFrequencyData()
89+
drawFrame(snapshotCanvas, snapshotContext2d, response)
90+
output.innerHTML =
91+
`
92+
\nByte Frequency Data
93+
94+
\nSize: ${response.length}
95+
\n${response.toString().replace(/,/g, '\n')}
96+
`
97+
}
98+
99+
floatTimeDomainButton.onclick = async () => {
100+
const response = await analyserNode.getFloatTimeDomainData()
101+
102+
output.innerHTML =
103+
`
104+
\nFloat Time Domain Data
105+
106+
\nSize: ${response.length}
107+
\n${response.toString().replace(/,/g, '\n')}
108+
`
109+
}
110+
111+
byteTimeDomainButton.onclick = async () => {
112+
const response = await analyserNode.getByteTimeDomainData()
113+
drawFrame(snapshotCanvas, snapshotContext2d, response)
114+
output.innerHTML =
115+
`
116+
\nByte Time Domain Data
117+
118+
\nSize: ${response.length}
119+
\n${response.toString().replace(/,/g, '\n')}
120+
`
121+
}
122+
123+
124+
})()
125+
</script>
126+
</html>

dist/bundle.js

Lines changed: 26 additions & 17 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

dist/bundle.min.js

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

dist/processor.worklet.js

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

dist/src/node/index.d.ts

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,15 +3,14 @@ declare type AdvancedAnalyserNodeProperties = {
33
dataAsByteArray: boolean;
44
fftSize?: number;
55
samplesBetweenTransforms?: number;
6+
timeDomainSamplesCount?: number;
67
windowFunction?: WindowingFunctionTypes;
78
};
89
export declare class AdvancedAnalyserNode extends AudioWorkletNode {
9-
fftSize: number;
10-
samplesBetweenTransforms?: number;
1110
_portMapId: number;
1211
_portMap: Map<any, any>;
1312
_eventListenersCount: Record<EventListenerTypes, EventListenerOrEventListenerObject[]>;
14-
constructor(context: BaseAudioContext, { fftSize, samplesBetweenTransforms, windowFunction }: AudioWorkletNodeOptions & AdvancedAnalyserNodeProperties);
13+
constructor(context: BaseAudioContext, { fftSize, samplesBetweenTransforms, timeDomainSamplesCount, windowFunction }: AudioWorkletNodeOptions & AdvancedAnalyserNodeProperties);
1514
_uniqId(): number;
1615
_postMessage(message: Message, transfer?: Transferable[]): void;
1716
onprocessorerror: (err: Event) => void;

dist/src/processor/index.d.ts

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ export declare class AdvancedAnalyserProcessor extends AudioWorkletProcessor {
1010
_fftOutput: number[];
1111
_lastTransform: Float32Array;
1212
_samplesBetweenTransforms: number;
13+
_timeDomainSamplesCount: number;
1314
_windowFunctionType: WindowingFunctionTypes;
1415
_isListeningTo: Record<EventListenerTypes, boolean>;
1516
/**
@@ -28,6 +29,8 @@ export declare class AdvancedAnalyserProcessor extends AudioWorkletProcessor {
2829
_portMap: Map<any, any>;
2930
get _frequencyBinCount(): number;
3031
set frequencyBinCount(value: number);
32+
get _isListeningToFrequencyData(): boolean;
33+
get _isListeningToTimeDomainData(): boolean;
3134
static get parameterDescriptors(): {
3235
name: string;
3336
defaultValue: number;
@@ -36,12 +39,14 @@ export declare class AdvancedAnalyserProcessor extends AudioWorkletProcessor {
3639
processorOptions: {
3740
fftSize: number;
3841
samplesBetweenTransforms: number;
42+
timeDomainSamplesCount?: number;
3943
windowFunction?: WindowingFunctionTypes;
4044
};
4145
});
4246
_onmessage(message: Message): void;
4347
_postMessage(message: Message, transfer?: Transferable[]): void;
44-
_shouldFlush(): boolean;
48+
_shouldFlushFrequencies(): boolean;
49+
_shouldFlushTimeDomainData(): boolean;
4550
_appendToBuffer(value: number): void;
4651
/**
4752
* to clarify this as it could be a little confusing:
@@ -58,10 +63,13 @@ export declare class AdvancedAnalyserProcessor extends AudioWorkletProcessor {
5863
* [5, 6, 3, 4] => [3, 4, 5, 6]
5964
*/
6065
_updateFftInput(): void;
61-
_convertFloatToDb(destinationArray: Float32Array): void;
62-
_convertToByteData(destinationArray: Uint8Array): void;
66+
_fillArrayWithLastNSamples(destinationArray: Float32Array): void;
67+
_convertFrequenciesToDb(destinationArray: Float32Array): void;
68+
_convertFrequenciesToByteData(destinationArray: Uint8Array): void;
69+
_convertTimeDomainDataToByteData(data: Float32Array, destinationArray: Uint8Array): void;
6370
_doFft(): void;
64-
_flush(): void;
71+
_flushFrequencies(): void;
72+
_flushTimeDomainSamples(): void;
6573
_getFloatFrequencyData(requestId: number): void;
6674
_getByteFrequencyData(requestId: number): void;
6775
_getFloatTimeDomainData(requestId: number): void;

dist/src/types.d.ts

Lines changed: 20 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -3,16 +3,18 @@ export declare enum MessageTypes {
33
stop = 1,
44
frequencyDataAvailable = 2,
55
byteFrequencyDataAvailable = 3,
6-
getFloatFrequencyData = 4,
7-
requestedFloatFrequencyDataAvailable = 5,
8-
getByteFrequencyData = 6,
9-
requestedByteFrequencyDataAvailable = 7,
10-
getFloatTimeDomainData = 8,
11-
requestedFloatTimeDomainDataAvailable = 9,
12-
getByteTimeDomainData = 10,
13-
requestedByteTimeDomainDataAvailable = 11,
14-
startedListeningTo = 12,
15-
stoppedListeningTo = 13
6+
timeDomainDataAvailable = 4,
7+
byteTimeDomainDataAvailable = 5,
8+
getFloatFrequencyData = 6,
9+
requestedFloatFrequencyDataAvailable = 7,
10+
getByteFrequencyData = 8,
11+
requestedByteFrequencyDataAvailable = 9,
12+
getFloatTimeDomainData = 10,
13+
requestedFloatTimeDomainDataAvailable = 11,
14+
getByteTimeDomainData = 12,
15+
requestedByteTimeDomainDataAvailable = 13,
16+
startedListeningTo = 14,
17+
stoppedListeningTo = 15
1618
}
1719
interface BasicMessage<T, P = unknown> {
1820
type: T;
@@ -21,23 +23,25 @@ interface BasicMessage<T, P = unknown> {
2123
interface IdentifiedMessage<T, P = unknown> extends BasicMessage<T, P> {
2224
id: number;
2325
}
24-
declare type FloatFrequencyDataAvailableMessage = BasicMessage<MessageTypes.frequencyDataAvailable, Float32Array>;
25-
declare type ByteFrequencyDataAvailableMessage = BasicMessage<MessageTypes.byteFrequencyDataAvailable, Uint8Array>;
26+
declare type FloatFrequencyDataAvailableMessage = BasicMessage<MessageTypes.frequencyDataAvailable, ArrayBuffer>;
27+
declare type ByteFrequencyDataAvailableMessage = BasicMessage<MessageTypes.byteFrequencyDataAvailable, ArrayBuffer>;
28+
declare type FloatTimeDomainDataAvailableMessage = BasicMessage<MessageTypes.timeDomainDataAvailable, ArrayBuffer>;
29+
declare type ByteTimeDomainDataAvailableMessage = BasicMessage<MessageTypes.byteTimeDomainDataAvailable, ArrayBuffer>;
2630
declare type GetFloatFrequencyDataMessage = IdentifiedMessage<MessageTypes.getFloatFrequencyData>;
2731
declare type RequestedFloatFrequencyDataAvailableMessage = IdentifiedMessage<MessageTypes.requestedFloatFrequencyDataAvailable, ArrayBuffer>;
28-
declare type GetByteFrequencyDataMessage = IdentifiedMessage<MessageTypes.getByteFrequencyData, Uint8Array>;
32+
declare type GetByteFrequencyDataMessage = IdentifiedMessage<MessageTypes.getByteFrequencyData, ArrayBuffer>;
2933
declare type RequestedByteFrequencyDataAvailableMessage = IdentifiedMessage<MessageTypes.requestedByteFrequencyDataAvailable, ArrayBuffer>;
3034
declare type GetFloatTimeDomainDataMessage = IdentifiedMessage<MessageTypes.getFloatTimeDomainData>;
3135
declare type RequestedFloatTimeDomainDataAvailableMessage = IdentifiedMessage<MessageTypes.requestedFloatTimeDomainDataAvailable, ArrayBuffer>;
32-
declare type GetByteTimeDomainDataMessage = IdentifiedMessage<MessageTypes.getByteTimeDomainData, Uint8Array>;
36+
declare type GetByteTimeDomainDataMessage = IdentifiedMessage<MessageTypes.getByteTimeDomainData, ArrayBuffer>;
3337
declare type RequestedByteTimeDomainDataAvailableMessage = IdentifiedMessage<MessageTypes.requestedByteTimeDomainDataAvailable, ArrayBuffer>;
3438
declare type StartedListeningToMessage = BasicMessage<MessageTypes.startedListeningTo, EventListenerTypes>;
3539
declare type StoppedListeningToMessage = BasicMessage<MessageTypes.stoppedListeningTo, EventListenerTypes>;
36-
export declare type Message = FloatFrequencyDataAvailableMessage | ByteFrequencyDataAvailableMessage | GetFloatFrequencyDataMessage | RequestedFloatFrequencyDataAvailableMessage | GetByteFrequencyDataMessage | RequestedByteFrequencyDataAvailableMessage | GetFloatTimeDomainDataMessage | RequestedFloatTimeDomainDataAvailableMessage | GetByteTimeDomainDataMessage | RequestedByteTimeDomainDataAvailableMessage | StartedListeningToMessage | StoppedListeningToMessage;
40+
export declare type Message = FloatFrequencyDataAvailableMessage | ByteFrequencyDataAvailableMessage | FloatTimeDomainDataAvailableMessage | ByteTimeDomainDataAvailableMessage | GetFloatFrequencyDataMessage | RequestedFloatFrequencyDataAvailableMessage | GetByteFrequencyDataMessage | RequestedByteFrequencyDataAvailableMessage | GetFloatTimeDomainDataMessage | RequestedFloatTimeDomainDataAvailableMessage | GetByteTimeDomainDataMessage | RequestedByteTimeDomainDataAvailableMessage | StartedListeningToMessage | StoppedListeningToMessage;
3741
export declare enum ProcessorParameters {
3842
fftSize = "fftSize",
3943
samplesBetweenTransforms = "samplesBetweenTransforms",
40-
dataAsByteArray = "dataAsByteArray",
44+
timeDomainSamplesCount = "timeDomainSamplesCount",
4145
windowFunction = "windowFunction"
4246
}
4347
export declare enum EventListenerTypes {

dist/types.d.ts

Lines changed: 20 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -3,16 +3,18 @@ export declare enum MessageTypes {
33
stop = 1,
44
frequencyDataAvailable = 2,
55
byteFrequencyDataAvailable = 3,
6-
getFloatFrequencyData = 4,
7-
requestedFloatFrequencyDataAvailable = 5,
8-
getByteFrequencyData = 6,
9-
requestedByteFrequencyDataAvailable = 7,
10-
getFloatTimeDomainData = 8,
11-
requestedFloatTimeDomainDataAvailable = 9,
12-
getByteTimeDomainData = 10,
13-
requestedByteTimeDomainDataAvailable = 11,
14-
startedListeningTo = 12,
15-
stoppedListeningTo = 13
6+
timeDomainDataAvailable = 4,
7+
byteTimeDomainDataAvailable = 5,
8+
getFloatFrequencyData = 6,
9+
requestedFloatFrequencyDataAvailable = 7,
10+
getByteFrequencyData = 8,
11+
requestedByteFrequencyDataAvailable = 9,
12+
getFloatTimeDomainData = 10,
13+
requestedFloatTimeDomainDataAvailable = 11,
14+
getByteTimeDomainData = 12,
15+
requestedByteTimeDomainDataAvailable = 13,
16+
startedListeningTo = 14,
17+
stoppedListeningTo = 15
1618
}
1719
interface BasicMessage<T, P = unknown> {
1820
type: T;
@@ -21,23 +23,25 @@ interface BasicMessage<T, P = unknown> {
2123
interface IdentifiedMessage<T, P = unknown> extends BasicMessage<T, P> {
2224
id: number;
2325
}
24-
declare type FloatFrequencyDataAvailableMessage = BasicMessage<MessageTypes.frequencyDataAvailable, Float32Array>;
25-
declare type ByteFrequencyDataAvailableMessage = BasicMessage<MessageTypes.byteFrequencyDataAvailable, Uint8Array>;
26+
declare type FloatFrequencyDataAvailableMessage = BasicMessage<MessageTypes.frequencyDataAvailable, ArrayBuffer>;
27+
declare type ByteFrequencyDataAvailableMessage = BasicMessage<MessageTypes.byteFrequencyDataAvailable, ArrayBuffer>;
28+
declare type FloatTimeDomainDataAvailableMessage = BasicMessage<MessageTypes.timeDomainDataAvailable, ArrayBuffer>;
29+
declare type ByteTimeDomainDataAvailableMessage = BasicMessage<MessageTypes.byteTimeDomainDataAvailable, ArrayBuffer>;
2630
declare type GetFloatFrequencyDataMessage = IdentifiedMessage<MessageTypes.getFloatFrequencyData>;
2731
declare type RequestedFloatFrequencyDataAvailableMessage = IdentifiedMessage<MessageTypes.requestedFloatFrequencyDataAvailable, ArrayBuffer>;
28-
declare type GetByteFrequencyDataMessage = IdentifiedMessage<MessageTypes.getByteFrequencyData, Uint8Array>;
32+
declare type GetByteFrequencyDataMessage = IdentifiedMessage<MessageTypes.getByteFrequencyData, ArrayBuffer>;
2933
declare type RequestedByteFrequencyDataAvailableMessage = IdentifiedMessage<MessageTypes.requestedByteFrequencyDataAvailable, ArrayBuffer>;
3034
declare type GetFloatTimeDomainDataMessage = IdentifiedMessage<MessageTypes.getFloatTimeDomainData>;
3135
declare type RequestedFloatTimeDomainDataAvailableMessage = IdentifiedMessage<MessageTypes.requestedFloatTimeDomainDataAvailable, ArrayBuffer>;
32-
declare type GetByteTimeDomainDataMessage = IdentifiedMessage<MessageTypes.getByteTimeDomainData, Uint8Array>;
36+
declare type GetByteTimeDomainDataMessage = IdentifiedMessage<MessageTypes.getByteTimeDomainData, ArrayBuffer>;
3337
declare type RequestedByteTimeDomainDataAvailableMessage = IdentifiedMessage<MessageTypes.requestedByteTimeDomainDataAvailable, ArrayBuffer>;
3438
declare type StartedListeningToMessage = BasicMessage<MessageTypes.startedListeningTo, EventListenerTypes>;
3539
declare type StoppedListeningToMessage = BasicMessage<MessageTypes.stoppedListeningTo, EventListenerTypes>;
36-
export declare type Message = FloatFrequencyDataAvailableMessage | ByteFrequencyDataAvailableMessage | GetFloatFrequencyDataMessage | RequestedFloatFrequencyDataAvailableMessage | GetByteFrequencyDataMessage | RequestedByteFrequencyDataAvailableMessage | GetFloatTimeDomainDataMessage | RequestedFloatTimeDomainDataAvailableMessage | GetByteTimeDomainDataMessage | RequestedByteTimeDomainDataAvailableMessage | StartedListeningToMessage | StoppedListeningToMessage;
40+
export declare type Message = FloatFrequencyDataAvailableMessage | ByteFrequencyDataAvailableMessage | FloatTimeDomainDataAvailableMessage | ByteTimeDomainDataAvailableMessage | GetFloatFrequencyDataMessage | RequestedFloatFrequencyDataAvailableMessage | GetByteFrequencyDataMessage | RequestedByteFrequencyDataAvailableMessage | GetFloatTimeDomainDataMessage | RequestedFloatTimeDomainDataAvailableMessage | GetByteTimeDomainDataMessage | RequestedByteTimeDomainDataAvailableMessage | StartedListeningToMessage | StoppedListeningToMessage;
3741
export declare enum ProcessorParameters {
3842
fftSize = "fftSize",
3943
samplesBetweenTransforms = "samplesBetweenTransforms",
40-
dataAsByteArray = "dataAsByteArray",
44+
timeDomainSamplesCount = "timeDomainSamplesCount",
4145
windowFunction = "windowFunction"
4246
}
4347
export declare enum EventListenerTypes {

0 commit comments

Comments
 (0)