Esempio n. 1
0
        /// <summary>
        /// Decoded data into the buffer
        /// </summary>
        /// <returns></returns>
        private bool FillBuffer()
        {
            var packet = GetNextEncodedData();

            if (!packet.HasValue)
            {
                //Debug.Log("empty");
                return(false);
            }
            // Don't make the decoder unless we know that we'll have to
            if (_decoder == null)
            {
                _decoder = new OpusDecoder(_outputSampleRate, _outputChannelCount);
            }

            if (_decodedBuffer[_nextBufferToDecodeInto] == null)
            {
                _decodedBuffer[_nextBufferToDecodeInto] = new float[SubBufferSize];
            }

            //Debug.Log("decoding " + packet.Value.Sequence + "  expected=" + _nextSequenceToDecode + " last=" + _lastReceivedSequence + " len=" + packet.Value.Data.Length);
            if (_nextSequenceToDecode != 0)
            {
                long seqDiff = packet.Value.Sequence - _nextSequenceToDecode;

                // If new packet is VERY late, then the sequence number has probably reset
                if (seqDiff < -MaxMissingPackets)
                {
                    Debug.Log("Sequence has possibly reset diff = " + seqDiff);
                    _decoder.ResetState();
                }
                // If the packet came before we were expecting it to, but after the last packet, the sampling has probably changed
                // unless the packet is a last packet (in which case the sequence may have only increased by 1)
                else if (packet.Value.Sequence > _lastReceivedSequence && seqDiff < 0 && !packet.Value.IsLast)
                {
                    Debug.Log("Mumble sample rate may have changed");
                }
                // If the sequence number changes abruptly (which happens with push to talk)
                else if (seqDiff > MaxMissingPackets)
                {
                    Debug.Log("Mumble packet sequence changed abruptly pkt: " + packet.Value.Sequence + " last: " + _lastReceivedSequence);
                }
                // If the packet is a bit late, drop it
                else if (seqDiff < 0 && !packet.Value.IsLast)
                {
                    Debug.LogWarning("Received old packet " + packet.Value.Sequence + " expecting " + _nextSequenceToDecode);
                    return(false);
                }
                // If we missed a packet, add a null packet to tell the decoder what happened
                else if (seqDiff > 0)
                {
                    //Debug.LogWarning("dropped packet, recv: " + packet.Value.Sequence + ", expected " + _nextSequenceToDecode);
                    NumPacketsLost += packet.Value.Sequence - _nextSequenceToDecode;
                    int emptySampleNumRead = _decoder.Decode(null, _decodedBuffer[_nextBufferToDecodeInto]);
                    _decodedCount += emptySampleNumRead;
                    _numSamplesInBuffer[_nextBufferToDecodeInto] = emptySampleNumRead;
                    _readOffsetInBuffer[_nextBufferToDecodeInto] = 0;
                    _nextSequenceToDecode = packet.Value.Sequence + emptySampleNumRead / ((_outputSampleRate / 100) * _outputChannelCount);
                    _nextBufferToDecodeInto++;
                    //Make sure we don't go over our max number of buffers
                    if (_nextBufferToDecodeInto == NumDecodedSubBuffers)
                    {
                        _nextBufferToDecodeInto = 0;
                    }
                    if (_decodedBuffer[_nextBufferToDecodeInto] == null)
                    {
                        _decodedBuffer[_nextBufferToDecodeInto] = new float[SubBufferSize];
                    }
                    //Debug.Log("Null read returned: " + emptySampleNumRead + " samples");
                }
            }

            int numRead = 0;

            if (packet.Value.Data.Length != 0)
            {
                numRead = _decoder.Decode(packet.Value.Data, _decodedBuffer[_nextBufferToDecodeInto]);
            }
            else
            {
                Debug.LogError("empty packet data?");
            }

            if (numRead < 0)
            {
                Debug.Log("num read is < 0");
                return(false);
            }

            _decodedCount += numRead;
            _numSamplesInBuffer[_nextBufferToDecodeInto] = numRead;
            _readOffsetInBuffer[_nextBufferToDecodeInto] = 0;
            //Debug.Log("numRead = " + numRead);
            _lastReceivedSequence = packet.Value.Sequence;
            if (!packet.Value.IsLast)
            {
                _nextSequenceToDecode = packet.Value.Sequence + numRead / ((_outputSampleRate / 100) * _outputChannelCount);
            }
            else
            {
                //Debug.Log("Resetting decoder");
                _nextSequenceToDecode  = 0;
                HasFilledInitialBuffer = false;
                _decoder.ResetState();
            }
            if (numRead > 0)
            {
                _nextBufferToDecodeInto++;
            }
            //Make sure we don't go over our max number of buffers
            if (_nextBufferToDecodeInto == NumDecodedSubBuffers)
            {
                _nextBufferToDecodeInto = 0;
            }
            return(true);
        }
Esempio n. 2
0
        private void DecodeThread()
        {
            while (!_isDisposing)
            {
                _waitHandle.WaitOne();
                // Keep looping until either disposed
                // or the message queue is depleted
                while (!_isDisposing)
                {
                    try
                    {
                        MessageData messageData;
                        lock (_messageQueue)
                        {
                            if (_messageQueue.Count == 0)
                            {
                                break;
                            }
                            messageData = _messageQueue.Dequeue();
                        }

                        OpusDecoder  decoder = null;
                        DecoderState decoderState;

                        switch (messageData.TypeOfMessage)
                        {
                        case MessageType.AllocDecoderState:
                            // If we receive an alloc decoder state message
                            // then we just need make an entry for it in
                            // current decoders. We don't bother assigning
                            // an actual opus decoder until we get data
                            // this is because there may be lots of users
                            // in current decoders, but only a few of them
                            // actually are sending audio
                            _currentDecoders[messageData.Session] = new DecoderState();
                            //Debug.Log("Alloc'd DecoderState for session: " + messageData.Session);
                            break;

                        case MessageType.FreeDecoder:
                            if (_currentDecoders.TryGetValue(messageData.Session, out decoderState))
                            {
                                // Return the OpusDecoder
                                if (decoderState.Decoder != null)
                                {
                                    _unusedDecoders.Enqueue(decoderState.Decoder);
                                }
                                _currentDecoders.Remove(messageData.Session);
                                //Debug.Log("Removing DecoderState for session: " + messageData.Session);
                            }
                            else
                            {
                                Debug.Log("Failed to remove decoder for session: " + messageData.Session);
                            }
                            break;

                        case MessageType.DecompressData:
                            // Drop this audio, if there's no assigned decoder ready to receive it
                            if (!_currentDecoders.TryGetValue(messageData.Session, out decoderState))
                            {
                                Debug.LogWarning("No DecoderState for session: " + messageData.Session);
                                break;
                            }
                            // Make an OpusDecoder if there isn't one
                            if (decoderState.Decoder == null)
                            {
                                if (_unusedDecoders.Count > 0)
                                {
                                    decoder = _unusedDecoders.Dequeue();
                                    decoder.ResetState();
                                }
                                else
                                {
                                    decoder = new OpusDecoder(_outputSampleRate, _outputChannelCount);
                                }
                                //Debug.Log("Added OpusDecoder for DecoderState session: " + messageData.Session);
                                decoderState.Decoder = decoder;
                            }
                            DecodeAudio(messageData.Session, decoderState, messageData.CompressedAudio, messageData.PosData, messageData.Sequence,
                                        messageData.IsLast);
                            break;

                        default:
                            Debug.LogError("Message type not implemented:" + messageData.TypeOfMessage);
                            break;
                        }
                    }catch (Exception e)
                    {
                        Debug.LogError("Exception in decode thread: " + e.ToString());
                    }
                }
            }
        }