Path: blob/main/misc/emulator/gba/user_scripts/XAudioJS/XAudioServerMediaStreamWorker.js
28798 views
//This file is part of the XAudioJS library.1var XAudioJSResampledBuffer = [];2var XAudioJSOutputBuffer = [];3var XAudioJSResampleBufferStart = 0;4var XAudioJSResampleBufferEnd = 0;5var XAudioJSResampleBufferSize = 0;6var XAudioJSChannelsAllocated = 1;7//Message Receiver:8self.onmessage = function (event) {9var data = event.data;10switch (data[0]) {11case 0:12//Add new audio samples to our ring buffer:13var resampledResult = data[1];14var length = resampledResult.length;15for (var i = 0; i < length; ++i) {16XAudioJSResampledBuffer[XAudioJSResampleBufferEnd++] = resampledResult[i];17if (XAudioJSResampleBufferEnd == XAudioJSResampleBufferSize) {18XAudioJSResampleBufferEnd = 0;19}20if (XAudioJSResampleBufferStart == XAudioJSResampleBufferEnd) {21XAudioJSResampleBufferStart += XAudioJSChannelsAllocated;22if (XAudioJSResampleBufferStart == XAudioJSResampleBufferSize) {23XAudioJSResampleBufferStart = 0;24}25}26}27break;28case 1:29//Initialize:30XAudioJSResampleBufferSize = data[1];31XAudioJSChannelsAllocated = data[2];32XAudioJSResampledBuffer = new Float32Array(XAudioJSResampleBufferSize);33}34}35//MediaStream Polyfill Event:36self.onprocessmedia = function (event) {37//Get some buffer length computations:38var apiBufferLength = event.audioLength;39var apiBufferLengthAll = apiBufferLength * event.audioChannels;40if (apiBufferLengthAll > XAudioJSOutputBuffer.length) {41XAudioJSOutputBuffer = new Float32Array(apiBufferLengthAll);42}43//De-interleave the buffered audio while looping through our ring buffer:44var sampleFramesCount = Math.min(apiBufferLength, XAudioJSResampledSamplesLeft() / XAudioJSChannelsAllocated);45for (var sampleFramePosition = 0, channelOffset = 0; sampleFramePosition < sampleFramesCount; ++sampleFramePosition) {46for (channelOffset = sampleFramePosition; channelOffset < apiBufferLengthAll; channelOffset += apiBufferLength) {47XAudioJSOutputBuffer[channelOffset] = XAudioJSResampledBuffer[XAudioJSResampleBufferStart++];48if (XAudioJSResampleBufferStart == XAudioJSResampleBufferSize) {49XAudioJSResampleBufferStart = 0;50}51}52}53//Add some zero fill if we underran the required buffer fill amount:54while (sampleFramePosition < apiBufferLength) {55for (channelOffset = sampleFramePosition++; channelOffset < apiBufferLengthAll; channelOffset += apiBufferLength) {56XAudioJSOutputBuffer[channelOffset] = 0;57}58}59//Write some buffered audio:60event.writeAudio(XAudioJSOutputBuffer.subarray(0, apiBufferLengthAll));61//Request a buffer from the main thread:62self.postMessage(event.audioLength);63}64//Accessory function used to determine remaining samples in the ring buffer:65function XAudioJSResampledSamplesLeft() {66return ((XAudioJSResampleBufferStart <= XAudioJSResampleBufferEnd) ? 0 : XAudioJSResampleBufferSize) + XAudioJSResampleBufferEnd - XAudioJSResampleBufferStart;67}6869