@@ -8,87 +8,63 @@ import { loadRnnoise, RnnoiseWorkletNode } from '@sapphi-red/web-noise-suppresso
88let audioContext : AudioContext | null = null
99let rnnoiseWorklet : RnnoiseWorkletNode | null = null
1010const workletConsumers = new Set < symbol > ( )
11- const workletCleanupCallbackMap = new Map < symbol , ( ) => void > ( )
1211
1312/**
1413 * Creates and registers global RNNoiseWorkletNode and AudioContext.
1514 *
1615 * @returns A promise that resolves with a unique symbol
1716 * representing the consumer. This symbol must be passed to
18- * `unregisterNoiseSuppressionWorklet ` when the consumer is done.
17+ * `destroyNoiseSuppressionWorklet ` when the consumer is done.
1918 */
20- export async function registerNoiseSuppressionWorklet ( ) : Promise < symbol | null > {
19+ export async function registerNoiseSuppressionWorklet ( ) : Promise < symbol > {
2120 const consumer = Symbol ( 'noise-suppression-consumer' )
2221 workletConsumers . add ( consumer )
2322
2423 if ( audioContext && rnnoiseWorklet ) {
25- if ( audioContext . state === 'suspended' ) {
26- await audioContext . resume ( )
27- }
28-
2924 // Already registered
3025 return consumer
3126 }
3227
33- try {
34- audioContext = new AudioContext ( )
35- const rnnoiseWasmBinary = await loadRnnoise ( {
36- url : new URL (
37- '../../node_modules/@sapphi-red/web-noise-suppressor/dist/rnnoise.wasm' ,
38- import . meta. url ,
39- ) . pathname ,
40- simdUrl : new URL (
41- '../../node_modules/@sapphi-red/web-noise-suppressor/dist/rnnoise_simd.wasm' ,
42- import . meta. url ,
43- ) . pathname ,
44- } )
45- await audioContext . audioWorklet . addModule ( new URL (
46- '../../node_modules/@sapphi-red/web-noise-suppressor/dist/rnnoise/workletProcessor.js' ,
28+ audioContext = new AudioContext ( )
29+ const rnnoiseWasmBinary = await loadRnnoise ( {
30+ url : new URL (
31+ '../../node_modules/@sapphi-red/web-noise-suppressor/dist/rnnoise.wasm' ,
4732 import . meta. url ,
48- ) . pathname )
49- rnnoiseWorklet = new RnnoiseWorkletNode ( audioContext , {
50- wasmBinary : rnnoiseWasmBinary ,
51- maxChannels : 2 ,
52- } )
53-
54- if ( audioContext . state === 'suspended' ) {
55- await audioContext . resume ( )
56- }
57-
58- return consumer
59- } catch ( error ) {
60- console . error ( 'Error initializing RNNoiseWorklet:' , error )
61- await destroyNoiseSuppressionWorklet ( )
62- workletConsumers . delete ( consumer )
63- return null
64- }
33+ ) . pathname ,
34+ simdUrl : new URL (
35+ '../../node_modules/@sapphi-red/web-noise-suppressor/dist/rnnoise_simd.wasm' ,
36+ import . meta. url ,
37+ ) . pathname ,
38+ } )
39+ await audioContext . audioWorklet . addModule ( new URL (
40+ '../../node_modules/@sapphi-red/web-noise-suppressor/dist/rnnoise/workletProcessor.js' ,
41+ import . meta. url ,
42+ ) . pathname )
43+ rnnoiseWorklet = new RnnoiseWorkletNode ( audioContext , {
44+ wasmBinary : rnnoiseWasmBinary ,
45+ maxChannels : 2 ,
46+ } )
47+
48+ return consumer
6549}
6650
6751/**
68- * Unregister consumer from the global RNNoiseWorkletNode and AudioContext
52+ * Destroys the global RNNoiseWorkletNode and AudioContext
6953 * if there are no other worklet consumers left.
7054 *
7155 * @param consumer The symbol returned by `registerNoiseSuppressionWorklet`.
7256 */
73- export async function unregisterNoiseSuppressionWorklet ( consumer : symbol ) {
57+ export async function destroyNoiseSuppressionWorklet ( consumer : symbol ) {
7458 if ( ! workletConsumers . has ( consumer ) ) {
7559 return
7660 }
7761
78- cleanupNoiseSuppressionWorklet ( consumer )
7962 workletConsumers . delete ( consumer )
8063
8164 if ( workletConsumers . size > 0 ) {
8265 return
83- } else {
84- await destroyNoiseSuppressionWorklet ( )
8566 }
86- }
8767
88- /**
89- * Destroys the global RNNoiseWorkletNode and AudioContext
90- */
91- export async function destroyNoiseSuppressionWorklet ( ) {
9268 if ( rnnoiseWorklet ) {
9369 try {
9470 rnnoiseWorklet ?. disconnect ( )
@@ -113,10 +89,9 @@ export async function destroyNoiseSuppressionWorklet() {
11389 * Requires that RNNoiseWorklet has been asynchronously registered beforehand.
11490 *
11591 * @param stream - MediaStream to process
116- * @param consumer - Unique consumer id returned by `registerNoiseSuppressionWorklet`
11792 * @param enabled - Whether noise suppression is enabled
11893 */
119- export function processNoiseSuppression ( stream : MediaStream , consumer : symbol | null , enabled = false ) : MediaStream {
94+ export function processNoiseSuppression ( stream : MediaStream , enabled = false ) : MediaStream {
12095 if ( ! enabled ) {
12196 // No noise suppression requested; return the original stream
12297 return stream
@@ -127,32 +102,24 @@ export function processNoiseSuppression(stream: MediaStream, consumer: symbol |
127102 return stream
128103 }
129104
130- if ( ! audioContext || ! rnnoiseWorklet || ! consumer ) {
105+ if ( ! audioContext || ! rnnoiseWorklet ) {
131106 return stream
132107 }
133108
134- cleanupNoiseSuppressionWorklet ( consumer )
135- return processRnnoise ( stream , consumer )
109+ return processRnnoise ( stream )
136110}
137111
138112/**
139113 * Connects the RNNoiseWorklet to the given MediaStream and returns a new MediaStream with noise suppression applied.
140114 *
141115 * @param stream - MediaStream to process
142- * @param consumer - Unique consumer id returned by `registerNoiseSuppressionWorklet`
143116 */
144- export function processRnnoise ( stream : MediaStream , consumer : symbol ) : MediaStream {
117+ export function processRnnoise ( stream : MediaStream ) : MediaStream {
145118 try {
146119 const mediaStreamAudioSource = audioContext ! . createMediaStreamSource ( stream )
147- const outputGainNode = audioContext ! . createGain ( )
148120 const mediaStreamAudioDestinationNode = audioContext ! . createMediaStreamDestination ( )
149-
150- // Gain node configuration (to increase the output of processed track)
151- outputGainNode . gain . value = 2
152-
153121 mediaStreamAudioSource . connect ( rnnoiseWorklet ! )
154- rnnoiseWorklet ! . connect ( outputGainNode )
155- outputGainNode . connect ( mediaStreamAudioDestinationNode )
122+ rnnoiseWorklet ! . connect ( mediaStreamAudioDestinationNode )
156123
157124 const processedAudioTrack = mediaStreamAudioDestinationNode . stream . getAudioTracks ( ) [ 0 ]
158125 if ( ! processedAudioTrack ) {
@@ -164,33 +131,9 @@ export function processRnnoise(stream: MediaStream, consumer: symbol): MediaStre
164131 stream . removeTrack ( track )
165132 }
166133 stream . addTrack ( processedAudioTrack )
167-
168- workletCleanupCallbackMap . set ( consumer , ( ) => {
169- try {
170- mediaStreamAudioSource . disconnect ( rnnoiseWorklet ! )
171- rnnoiseWorklet ! . disconnect ( outputGainNode )
172- outputGainNode . disconnect ( mediaStreamAudioDestinationNode )
173- mediaStreamAudioDestinationNode . disconnect ( )
174- } catch ( error ) {
175- console . error ( error )
176- }
177- processedAudioTrack . stop ( )
178- } )
179134 } catch ( error ) {
180135 console . error ( 'Error processing noise suppression:' , error )
181136 }
182137
183138 return stream
184139}
185-
186- /**
187- * Cleans up the processing nodes currently associated with a consumer.
188- *
189- * @param consumer - Unique consumer id returned by `registerNoiseSuppressionWorklet`
190- */
191- function cleanupNoiseSuppressionWorklet ( consumer : symbol ) {
192- if ( workletCleanupCallbackMap . has ( consumer ) ) {
193- workletCleanupCallbackMap . get ( consumer ) ! ( )
194- workletCleanupCallbackMap . delete ( consumer )
195- }
196- }
0 commit comments