public BigArray <float> DecodeFrame(VoicePacketWrapper data)
        {
            int          frameSize = frameSizes[data.Frequency * 1000];
            codecWrapper codec     = encoders[data.Frequency * 1000];

            short[] decodedFrame16Bit = TempArray <short> .Obtain(frameSize * 4);

            int decoded = codec.decoder.Decode(data.RawData, 0, data.RawData.Length, decodedFrame16Bit, 0, false);

            if (tempOutputArray.Length != decoded)
            {
                tempOutputArray.Resize(decoded);
            }

            for (int i = 0; i < decoded; i++)
            {
                float val = (float)decodedFrame16Bit[i];
                val /= short.MaxValue;
                tempOutputArray[i] = val;
            }

            TempArray <short> .Release(decodedFrame16Bit);

            return(tempOutputArray);
        }
        protected override void OnAudioDataEncoded(VoicePacketWrapper encodedFrame)
        {
            if (Random.Range(0f, 1f) <= PacketLoss)
            {
                return;
            }

            ReceiveAudioData(encodedFrame);
        }
        public SpeexCodec(bool VBR)
        {
            encoders = new Dictionary <int, codecWrapper>()
            {
                { 8000, new codecWrapper(NSpeex.BandMode.Narrow, VBR) },
                { 16000, new codecWrapper(NSpeex.BandMode.Wide, VBR) },
                { 32000, new codecWrapper(NSpeex.BandMode.UltraWide, VBR) },
            };

            chunkBuffer       = new ChunkBuffer();
            tempOutputArray   = new BigArray <float>(1024, 0);
            tempPacketWrapper = new VoicePacketWrapper(0, 16, new byte[0]);
        }
        public VoicePacketWrapper?GetNextEncodedFrame(int frequency)
        {
            int          frameSize = frameSizes[frequency];
            codecWrapper codec     = encoders[frequency];

            float[] chunk = TempArray <float> .Obtain(frameSize);

            bool chunkAvailable = chunkBuffer.RetrieveChunk(chunk);

            if (!chunkAvailable)
            {
                TempArray <float> .Release(chunk);

                return(null);
            }

            tempPacketWrapper           = new VoicePacketWrapper();
            tempPacketWrapper.Frequency = (byte)(frequency / 1000);

            short[] audio16bit = TempArray <short> .Obtain(frameSize);

            for (int i = 0; i < frameSize; i++)
            {
                float val = chunk[i] * short.MaxValue;
                audio16bit[i] = (short)val;
            }
            TempArray <float> .Release(chunk);

            byte[] buffer = TempArray <byte> .Obtain(audio16bit.Length * 2);

            int encoded = codec.encoder.Encode(audio16bit, 0, frameSize, buffer, 0, buffer.Length);

            TempArray <short> .Release(audio16bit);

            tempPacketWrapper.RawData = new byte[encoded];

            System.Buffer.BlockCopy(buffer, 0, tempPacketWrapper.RawData, 0, encoded);

            TempArray <byte> .Release(buffer);

            return(tempPacketWrapper);
        }
        /// <summary>
        /// Decode and play back received audio data
        /// </summary>
        protected virtual void ReceiveAudioData(VoicePacketWrapper encodedFrame)
        {
            if (!IsLocal || DebugAudio)
            {
                //Debug.Log("encoded index" + encodedFrame.Index + " next expected" + nextExpectedIndex);
                // discard old samples
                if (encodedFrame.Index < nextExpectedIndex)
                {
                    return;
                }


                // voice controller is muted - don't bother decoding or buffering audio data
                if (Mute)
                {
                    nextExpectedIndex = encodedFrame.Index + 1;
                    return;
                }

                speaker.SetSampleRate(encodedFrame.Frequency * 1000);

                // some frames were lost, generate filler data for them
                // unless the speaker isn't playing any sound, in which case filler data will only delay the stream further
                // OR unless nextExpectedIndex is zero, implying that we haven't received any frames yet
                if (nextExpectedIndex != 0 && encodedFrame.Index != nextExpectedIndex && speaker.PlayingSound)
                {
                    int numMissingFrames = (int)(encodedFrame.Index - nextExpectedIndex);

                    for (int i = 0; i < numMissingFrames; i++)
                    {
                        BigArray <float> filler = codec.GenerateMissingFrame(encodedFrame.Frequency);
                        speaker.BufferAudio(filler);
                    }
                }

                BigArray <float> decoded = codec.DecodeFrame(encodedFrame);
                speaker.BufferAudio(decoded);

                nextExpectedIndex = encodedFrame.Index + 1;
            }
        }
        /// <summary>
        /// Called when new audio is available from the microphone
        /// </summary>
        protected virtual void OnMicrophoneDataReady(BigArray <float> newData, int frequency)
        {
            if (!IsLocal)
            {
                return;
            }

            codec.OnAudioAvailable(newData);

            VoicePacketWrapper?enc = codec.GetNextEncodedFrame(frequency);

            while (enc.HasValue)
            {
                // assign index
                VoicePacketWrapper packet = enc.Value;
                packet.Index = nextFrameIndex++;
                enc          = packet;

                OnAudioDataEncoded(enc.Value);
                enc = codec.GetNextEncodedFrame(frequency);
            }
        }
 /// <summary>
 /// Called when a frame of audio is encoded and ready to send
 /// </summary>
 protected virtual void OnAudioDataEncoded(VoicePacketWrapper encodedFrame)
 {
     // TODO: send audio over network
 }
Example #8
0
        void vc(byte[] headers, byte[] rawData)
        {
            VoicePacketWrapper packet = new VoicePacketWrapper(headers, rawData);

            ReceiveAudioData(packet);
        }
Example #9
0
 protected override void OnAudioDataEncoded(VoicePacketWrapper encodedFrame)
 {
     byte[] headers = encodedFrame.ObtainHeaders();
     GetComponent <NetworkView>().RPC("vc", RPCMode.All, headers, encodedFrame.RawData);
     encodedFrame.ReleaseHeaders();
 }