Newer
Older
safe_production_front / public / DispatchLib / DispatchAudioWorklet.js
wangxitong on 16 Aug 9 KB first commit
class DispatchAudioWorkletClass extends AudioWorkletProcessor {
    constructor() {
        super();

        this.BufferLen = 0;             //缓冲区长度 共享内存模式:缓冲区总长度 消息模式:单次消息长度
        this.MessageBufferLen = 0;

        this.Shared_Buffer = false;     //是否启用SharedArrayBuffer 共享内存模式

        this.Audio_Play_Empty = new Int16Array(128);          //空帧

        //共享内存模式相关
        this.AudioBuffer_Play_Left = null;      //左声道播放缓冲区
        this.AudioBuffer_Play_Right = null;     //右声道播放缓冲区
        this.Audio_Play_Write_Index = null;     //播放缓冲区写地址
        this.Audio_Play_Read_Index = null;      //播放缓冲区读地址
        this.Audio_Play_Length = null;          //播放缓冲区长度

        this.AudioBuffer_Capture = null;        //采集缓冲区
        this.Audio_Capture_Flag = null;         //采集标志位
        this.Audio_Capture_Write_Index = null;  //采集缓冲区写地址
        this.Audio_Capture_Read_Index = null;   //采集缓冲区读指针
        this.Audio_Capture_Length = null;       //采集缓冲区长度

        this.Audio_Play_Len = 0;

        /*
        DispatchPocLib.AudioWorkletNode.port.postMessage({
            Msg: "AudioEcho",
            start: 0,
        })
        
        */
        this.AudioEcho = 0;

        var self = this;        
        this.port.onmessage = event => {
            if (event && event.data && event.data.Msg) {
                if (event.data.Msg == "AudioBufferInit") {
                    if (event.data.Mode == "SharedArrayBuffer") {
                        self.Shared_Buffer = true;
                        self.BufferLen = event.data.BufferLen;
                        self.MessageBufferLen = event.data.Message_BufferLen;

                        self.AudioBuffer_Play_Left = new Int16Array(event.data.Shared_Play_Left);
                        self.AudioBuffer_Play_Right = new Int16Array(event.data.Shared_Play_Right);
                        self.Audio_Play_Write_Index = new Uint32Array(event.data.Shared_Play_Write_Index);
                        self.Audio_Play_Read_Index = new Uint32Array(event.data.Shared_Play_Read_Index);
                        self.Audio_Play_Length = new Uint32Array(event.data.Shared_Play_Length);

                        self.AudioBuffer_Capture = new Int16Array(event.data.Shared_Capture);    
                        self.Audio_Capture_Flag = new Uint32Array(event.data.Shared_Capture_Flag);
                        self.Audio_Capture_Write_Index = new Uint32Array(event.data.Shared_Capture_Write_Index);
                        self.Audio_Capture_Read_Index = new Uint32Array(event.data.Shared_Capture_Read_Index);
                        self.Audio_Capture_Length = new Uint32Array(event.data.Shared_Capture_Length);

                    } else {

                        self.Shared_Buffer = false;
                        self.BufferLen = event.data.BufferLen;
                        self.MessageBufferLen = event.data.Message_BufferLen;

                        self.AudioBuffer_Play_Left = new Int16Array(event.data.BufferLen);
                        self.AudioBuffer_Play_Right = new Int16Array(event.data.BufferLen);
                        self.Audio_Play_Write_Index = new Uint32Array(1);
                        self.Audio_Play_Read_Index = new Uint32Array(1);
                        self.Audio_Play_Length = new Uint32Array(1);

                        self.AudioBuffer_Capture = new Int16Array(event.data.BufferLen);    
                        self.Audio_Capture_Flag = new Uint32Array(1);
                        self.Audio_Capture_Write_Index = new Uint32Array(1);
                        self.Audio_Capture_Read_Index = new Uint32Array(1);
                        self.Audio_Capture_Length = new Uint32Array(1);

                        self.Audio_Capture_Flag[0] = 0;

                    }

                    self.Audio_Play_Length[0] = 0;
                    self.Audio_Capture_Length[0] = 0;

                    for (var i = 0; i < 128; i++)
                    {
                        self.Audio_Play_Empty[i] = 0;
                    }
                }
                else if (event.data.Msg == "AudioCaptureStart")
                {
                    self.Audio_Capture_Flag[0] = 1
                    console.log("DispatchAudioWorklet AudioCaptureStart");
                }
                else if (event.data.Msg == "AudioCaptureStop")
                {
                    self.Audio_Capture_Flag[0] = 0
                    console.log("DispatchAudioWorklet AudioCaptureStop");
                }
                else if (event.data.Msg == "AudioPlayBuffer")
                {
                    self.AudioBuffer_Play_Left.set(event.data.BufferLeft, self.Audio_Play_Write_Index[0]);
                    self.AudioBuffer_Play_Right.set(event.data.BufferRight, self.Audio_Play_Write_Index[0]);

                    //console.log("DispatchAudioWorklet fill write_index:", self.Audio_Play_Write_Index[0], " len:", event.data.BufferLeft.length, "read_index:", self.Audio_Play_Read_Index[0]);

                    self.Audio_Play_Write_Index[0] = self.Audio_Play_Write_Index[0] + event.data.BufferLeft.length;
                    if (self.Audio_Play_Write_Index[0] >= self.BufferLen) {
                        self.Audio_Play_Write_Index[0] = 0;
                    }

                    self.Audio_Play_Length[0] = self.Audio_Play_Length[0] + event.data.BufferLeft.length;                    
                }
                else if (event.data.Msg == "AudioEcho")
                {
                    self.AudioEcho = event.data.start;
                }
            }
        }

        self.port.postMessage({
            Msg: "AudioWorkletInit",
        });

        console.log("DispatchAudioWorklet Begin");
    }

    process(inputs, outputs, parameters) { //Float32Array
        if (this.Audio_Capture_Read_Index !== null) {
            const frameLen = 128;
            var input = inputs[0][0];

            if (input && this.AudioEcho) {
                //回声测试
                outputs[0][0].set(input);
                outputs[0][1].set(input);
                return true;
            }

            //采集
            if (input && (this.Audio_Capture_Flag[0] == 1))
            {
                //Float32Array->Int16Array
                var cap_short = new Int16Array(frameLen);
                for (var i = 0; i < frameLen; i++)
                {
                    cap_short[i] = parseInt(32767*input[i]);
                }
                
                //写入缓冲区
                this.AudioBuffer_Capture.set(cap_short, this.Audio_Capture_Write_Index[0]);

                //写地址后移
                this.Audio_Capture_Write_Index[0] = this.Audio_Capture_Write_Index[0] + cap_short.length;

                this.Audio_Capture_Length[0] = this.Audio_Capture_Length[0] + cap_short.length;

                if (!this.Shared_Buffer)
                {
                    //消息模式
                    if (this.Audio_Capture_Write_Index[0] % this.MessageBufferLen == 0)
                    {
                        this.port.postMessage({
                            Msg: "AudioCapBuffer",
                            Buffer: this.AudioBuffer_Capture.subarray(this.Audio_Capture_Write_Index[0] - this.MessageBufferLen, this.Audio_Capture_Write_Index[0])
                        });
                    }
                }

                if (this.Audio_Capture_Write_Index[0] >= this.BufferLen) {
                    this.Audio_Capture_Write_Index[0] = 0;
                }

                //console.log("DispatchAudioWorklet Audio_Capture Write ", this.Audio_Capture_Write_Index[0], " len:", this.Audio_Capture_Length[0], " Read ",this.Audio_Capture_Read_Index[0]);
            }   

            //播放
            if (this.Audio_Play_Length[0] >= frameLen)
            {
                var play_float_left = new Float32Array(frameLen);
                for (var i = 0; i < frameLen; i++)
                {
                    play_float_left[i] = this.AudioBuffer_Play_Left[this.Audio_Play_Read_Index[0] + i] / 32767.0;
                }
                if (outputs[0][0])
                {
                    outputs[0][0].set(play_float_left);     //左声道
                }
                var play_float_right = new Float32Array(frameLen);
                for (var i = 0; i < frameLen; i++)
                {
                    play_float_right[i] = this.AudioBuffer_Play_Right[this.Audio_Play_Read_Index[0] + i] / 32767.0;
                }

                if (outputs[0][1])
                {
                    outputs[0][1].set(play_float_right);    //右声道
                }  
                
                this.Audio_Play_Read_Index[0] = this.Audio_Play_Read_Index[0] + frameLen;
                if (this.Audio_Play_Read_Index[0] >= this.BufferLen) {
                    this.Audio_Play_Read_Index[0] = 0;
                }

                this.Audio_Play_Length[0] = this.Audio_Play_Length[0] - frameLen;
            }
            else
            {
                if (outputs[0][0])
                {
                    outputs[0][0].set(this.Audio_Play_Empty);
                }
                if (outputs[0][1])
                {
                    outputs[0][1].set(this.Audio_Play_Empty);  
                }           
            }

        }


        return true;
    }
}

registerProcessor('DispatchAudioWorklet', DispatchAudioWorkletClass);