/// <summary>
 /// Add some raw PCM data to the buffer to send
 /// </summary>
 /// <param name="pcm"></param>
 /// <param name="target"></param>
 /// <param name="targetId"></param>
 public void Add(PcmArray pcm, SpeechTarget target, uint targetId)
 {
     lock (_unencodedBuffer)
     {
         _unencodedBuffer.Enqueue(new TargettedSpeech(pcm, target, targetId));
     }
 }
 public TargettedSpeech(bool stop = true)
 {
     IsStop   = stop;
     PcmData  = null;
     Target   = SpeechTarget.Normal;
     TargetId = 0;
 }
예제 #3
0
 /// <summary>
 /// Add some raw PCM data to the buffer to send
 /// </summary>
 /// <param name="pcm"></param>
 /// <param name="target"></param>
 /// <param name="targetId"></param>
 public void Add(PcmArray pcm, SpeechTarget target, uint targetId)
 {
     lock (_bufferLock)
     {
         _unencodedBuffer.Enqueue(new TargettedSpeech(pcm, target, targetId));
         Monitor.Pulse(_bufferLock);
     }
 }
            public TargettedSpeech(PcmArray pcm, SpeechTarget target, uint targetId)
            {
                TargetId = targetId;
                Target   = target;
                PcmData  = pcm;

                IsStop = false;
            }
예제 #5
0
        public void SendVoice(PcmArray pcm, SpeechTarget target, uint targetId)
        {
            _encodingBuffer.Add(pcm, target, targetId);

            if (!_encodingThread.IsAlive)
            {
                _encodingThread.Start();
            }
        }
예제 #6
0
        public void SendVoice(PcmArray pcm, SpeechTarget target, uint targetId)
        {
            _encodingBuffer.Add(pcm, target, targetId);

            if (_encodingThread == null)
            {
                _encodingThread = new Thread(EncodingThreadEntry)
                {
                    IsBackground = true
                };
                _encodingThread.Start();
            }
        }
예제 #7
0
 public void SendVoicePacket(PcmArray floatData)
 {
     // Don't send anything out if we're muted
     if (OurUserState == null ||
         OurUserState.Mute)
     {
         return;
     }
     if (_manageSendBuffer != null)
     {
         _manageSendBuffer.SendVoice(floatData, SpeechTarget.Normal, 0);
     }
 }
예제 #8
0
        public ArraySegment <byte> Encode(OpusEncoder encoder, out bool isStop, out bool isEmpty)
        {
            isStop  = false;
            isEmpty = false;
            PcmArray            nextPcmToSend = null;
            ArraySegment <byte> encoder_buffer;

            lock (_unencodedBuffer)
            {
                if (_unencodedBuffer.Count == 0)
                {
                    isEmpty = true;
                }
                else
                {
                    if (_unencodedBuffer.Count == 1 && _isWaitingToSendLastPacket)
                    {
                        isStop = true;
                    }

                    TargettedSpeech speech = _unencodedBuffer.Dequeue();
                    isStop        = isStop || speech.IsStop;
                    nextPcmToSend = speech.PcmData;

                    if (isStop)
                    {
                        _isWaitingToSendLastPacket = false;
                    }
                }
            }

            if (nextPcmToSend == null || nextPcmToSend.Pcm.Length == 0)
            {
                isEmpty = true;
            }

            encoder_buffer = isEmpty ? EmptyByteSegment : encoder.Encode(nextPcmToSend.Pcm);

            if (nextPcmToSend != null)
            {
                nextPcmToSend.IsAvailable = true;
            }

            if (isStop)
            {
                Debug.Log("Resetting encoder state");
                encoder.ResetState();
            }
            return(encoder_buffer);
        }
예제 #9
0
        public PcmArray GetAvailablePcmArray()
        {
            foreach (PcmArray ray in _pcmArrays)
            {
                if (ray.IsAvailable)
                {
                    ray.IsAvailable = false;
                    return(ray);
                }
            }
            PcmArray newArray = new PcmArray(_mumbleClient.NumSamplesPerOutgoingPacket, _pcmArrays.Count);

            _pcmArrays.Add(newArray);

            //Debug.Log("New buffer length is: " + _pcmArrays.Count);
            return(newArray);
        }
예제 #10
0
        void SendVoiceIfReady()
        {
            int currentPosition = Microphone.GetPosition(_currentMic);

            if (currentPosition < _previousPosition)
            {
                _numTimesLooped++;
            }

            int totalSamples = _numTimesLooped * NumSamplesInAudioClip + currentPosition;

            _previousPosition = currentPosition;

            while (totalSamples - _totalNumSamplesSent >= NumSamplesPerOutgoingPacket)
            {
                PcmArray newData = _mumbleClient.GetAvailablePcmArray();

                if (!_mumbleClient.UseSyntheticSource)
                {
                    _sendAudioClip.GetData(newData.Pcm, _totalNumSamplesSent % NumSamplesInAudioClip);
                }
                else
                {
                    TestingClipToUse.GetData(newData.Pcm, _totalNumSamplesSent % TestingClipToUse.samples);
                }

                _totalNumSamplesSent += NumSamplesPerOutgoingPacket;

                if (VoiceSendingType == MicType.Amplitude)
                {
                    if (AmplitudeHigherThan(MinAmplitude, newData.Pcm))
                    {
                        _sampleNumberOfLastMinAmplitudeVoice = _totalNumSamplesSent;
                    }
                    else
                    {
                        if (_totalNumSamplesSent > _sampleNumberOfLastMinAmplitudeVoice + _voiceHoldSamples)
                        {
                            return;
                        }
                    }
                }
                _mumbleClient.SendVoicePacket(newData);
            }
        }
        public ArraySegment <byte> Encode(OpusCodec codec, out bool isStop, out bool isEmpty)
        {
            isStop  = false;
            isEmpty = false;
            PcmArray nextPcmToSend = null;

            lock (_unencodedBuffer)
            {
                if (_unencodedBuffer.Count == 0)
                {
                    isEmpty = true;
                }
                else
                {
                    if (_unencodedBuffer.Count == 1 && _isWaitingToSendLastPacket)
                    {
                        isStop = true;
                        _isWaitingToSendLastPacket = false;
                    }

                    TargettedSpeech speech = _unencodedBuffer.Dequeue();
                    isStop = isStop || speech.IsStop;
                    if (!isStop)
                    {
                        nextPcmToSend             = speech.PcmData;
                        nextPcmToSend.IsAvailable = true;
                    }
                }
            }

            if (nextPcmToSend == null || nextPcmToSend.Pcm.Length == 0)
            {
                isEmpty = true;
            }

            if (isEmpty)
            {
                return(EmptyByteSegment);
            }

            //Debug.Log("Will encode: " + nextPcmToSend.Length);
            return(codec.Encode(nextPcmToSend.Pcm));
        }
예제 #12
0
        public PcmArray GetAvailablePcmArray()
        {
            foreach (PcmArray ray in _pcmArrays)
            {
                if (ray._refCount == 0)
                {
                    ray.Ref();
                    //Debug.Log("re-using buffer");
                    return(ray);
                }
            }
            PcmArray newArray = new PcmArray(_mumbleClient.NumSamplesPerOutgoingPacket, _pcmArrays.Count, _maxPositionalLength);

            _pcmArrays.Add(newArray);

            if (_pcmArrays.Count > 10)
            {
                Debug.LogWarning(_pcmArrays.Count + " audio buffers in-use. There may be a leak");
            }
            //Debug.Log("New buffer length is: " + _pcmArrays.Count);
            return(newArray);
        }
예제 #13
0
 public void ReleasePcmArray(PcmArray pcmArray)
 {
     //Debug.Log("releasing pcm");
     pcmArray.IsAvailable = true;
 }
예제 #14
0
 internal void ReleasePcmArray(PcmArray pcmArray)
 {
     _manageSendBuffer.ReleasePcmArray(pcmArray);
 }
예제 #15
0
        public CompressedBuffer Encode(OpusEncoder encoder, out bool isStop, out bool isEmpty)
        {
            isStop  = false;
            isEmpty = false;
            PcmArray            nextPcmToSend = null;
            ArraySegment <byte> encoder_buffer;


            lock (_bufferLock)
            {
                // Make sure we have data, or an end event
                if (_unencodedBuffer.Count == 0)
                {
                    Monitor.Wait(_bufferLock);
                }

                // If there are still no unencoded buffers, then we return an empty packet
                if (_unencodedBuffer.Count == 0)
                {
                    isEmpty = true;
                }
                else
                {
                    if (_unencodedBuffer.Count == 1 && _isWaitingToSendLastPacket)
                    {
                        isStop = true;
                    }

                    TargettedSpeech speech = _unencodedBuffer.Dequeue();
                    isStop        = isStop || speech.IsStop;
                    nextPcmToSend = speech.PcmData;

                    if (isStop)
                    {
                        _isWaitingToSendLastPacket = false;
                    }
                }
            }

            if (nextPcmToSend == null || nextPcmToSend.Pcm.Length == 0)
            {
                isEmpty = true;
            }

            encoder_buffer = isEmpty ? EmptyByteSegment : encoder.Encode(nextPcmToSend.Pcm);
            byte[] pos    = nextPcmToSend == null ? null : nextPcmToSend.PositionalData;
            int    posLen = nextPcmToSend == null ? 0 : nextPcmToSend.PositionalDataLength;

            if (nextPcmToSend != null)
            {
                nextPcmToSend.UnRef();
            }

            if (isStop)
            {
                Debug.Log("Resetting encoder state");
                encoder.ResetState();
            }


            CompressedBuffer compressedBuffer = new CompressedBuffer
            {
                EncodedData          = encoder_buffer,
                PositionalData       = pos,
                PositionalDataLength = posLen
            };

            return(compressedBuffer);
        }
예제 #16
0
        void SendVoiceIfReady()
        {
            int currentPosition = Microphone.GetPosition(_currentMic);

            //Debug.Log(currentPosition + " " + Microphone.IsRecording(_currentMic));

            //Debug.Log(currentPosition);
            if (currentPosition < _previousPosition)
            {
                _numTimesLooped++;
            }

            //Debug.Log("mic position: " + currentPosition + " was: " + _previousPosition + " looped: " + _numTimesLooped);

            int  totalSamples  = currentPosition + _numTimesLooped * NumSamplesInMicBuffer;
            bool isEmpty       = currentPosition == 0 && _previousPosition == 0;
            bool isFirstSample = _numTimesLooped == 0 && _previousPosition == 0;

            _previousPosition = currentPosition;
            if (isEmpty)
            {
                _secondsWithoutMicSamples += Time.deltaTime;
            }
            else
            {
                _secondsWithoutMicSamples = 0;
            }

            if (_secondsWithoutMicSamples > MaxSecondsWithoutMicData)
            {
                // For 5 times in a row, we received no usable data
                // this normally means that the mic we were using disconnected
                Debug.Log("Mic has disconnected!");
                StopSendingAudio();
                if (OnMicDisconnect != null)
                {
                    OnMicDisconnect();
                }
                return;
            }

            // We drop the first sample, because it generally starts with
            // a lot of pre-existing, stale, audio data which we couldn't
            // use b/c it's too old
            if (isFirstSample)
            {
                _totalNumSamplesSent = totalSamples;
                return;
            }

            while (totalSamples - _totalNumSamplesSent >= NumSamplesPerOutgoingPacket)
            {
                PcmArray newData = _mumbleClient.GetAvailablePcmArray();

                if (!_mumbleClient.UseSyntheticSource)
                {
                    SendAudioClip.GetData(newData.Pcm, _totalNumSamplesSent % NumSamplesInMicBuffer);
                }
                else
                {
                    TestingClipToUse.GetData(newData.Pcm, _totalNumSamplesSent % TestingClipToUse.samples);
                }
                //Debug.Log(Time.frameCount + " " + currentPosition);

                _totalNumSamplesSent += NumSamplesPerOutgoingPacket;

                if (VoiceSendingType == MicType.Amplitude)
                {
                    if (AmplitudeHigherThan(MinAmplitude, newData.Pcm))
                    {
                        _sampleNumberOfLastMinAmplitudeVoice = _totalNumSamplesSent;
                        if (OnMicData != null)
                        {
                            OnMicData(newData);
                        }
                        if (_writePositionalDataFunc != null)
                        {
                            _writePositionalDataFunc(ref newData.PositionalData, ref newData.PositionalDataLength);
                        }
                        else
                        {
                            newData.PositionalDataLength = 0;
                        }
                        _mumbleClient.SendVoicePacket(newData);
                    }
                    else
                    {
                        if (_totalNumSamplesSent > _sampleNumberOfLastMinAmplitudeVoice + _voiceHoldSamples)
                        {
                            newData.UnRef();
                            continue;
                        }
                        if (OnMicData != null)
                        {
                            OnMicData(newData);
                        }
                        if (_writePositionalDataFunc != null)
                        {
                            _writePositionalDataFunc(ref newData.PositionalData, ref newData.PositionalDataLength);
                        }
                        else
                        {
                            newData.PositionalDataLength = 0;
                        }
                        _mumbleClient.SendVoicePacket(newData);
                        // If this is the sample before the hold turns off, stop sending after it's sent
                        if (_totalNumSamplesSent + NumSamplesPerOutgoingPacket > _sampleNumberOfLastMinAmplitudeVoice + _voiceHoldSamples)
                        {
                            _mumbleClient.StopSendingVoice();
                        }
                    }
                }
                else
                {
                    if (OnMicData != null)
                    {
                        OnMicData(newData);
                    }
                    if (_writePositionalDataFunc != null)
                    {
                        _writePositionalDataFunc(ref newData.PositionalData, ref newData.PositionalDataLength);
                    }
                    else
                    {
                        newData.PositionalDataLength = 0;
                    }
                    _mumbleClient.SendVoicePacket(newData);
                }
            }
        }
예제 #17
0
        void SendVoiceIfReady()
        {
            int currentPosition = Microphone.GetPosition(_currentMic);

            //Debug.Log(currentPosition + " " + Microphone.IsRecording(_currentMic));

            if (currentPosition < _previousPosition)
            {
                _numTimesLooped++;
            }

            //int numSourceSamples = !_mumbleClient.UseSyntheticSource ? NumSamplesInMicBuffer : TestingClipToUse.samples;

            int totalSamples = currentPosition + _numTimesLooped * NumSamplesInMicBuffer;

            //int totalSamples = currentPosition + _numTimesLooped * numSourceSamples;
            _previousPosition = currentPosition;

            while (totalSamples - _totalNumSamplesSent >= NumSamplesPerOutgoingPacket)
            {
                PcmArray newData = _mumbleClient.GetAvailablePcmArray();

                if (!_mumbleClient.UseSyntheticSource)
                {
                    SendAudioClip.GetData(newData.Pcm, _totalNumSamplesSent % NumSamplesInMicBuffer);
                }
                else
                {
                    TestingClipToUse.GetData(newData.Pcm, _totalNumSamplesSent % TestingClipToUse.samples);
                }
                //Debug.Log(Time.frameCount + " " + currentPosition);

                _totalNumSamplesSent += NumSamplesPerOutgoingPacket;

                if (VoiceSendingType == MicType.Amplitude)
                {
                    if (AmplitudeHigherThan(MinAmplitude, newData.Pcm))
                    {
                        _sampleNumberOfLastMinAmplitudeVoice = _totalNumSamplesSent;
                        _mumbleClient.SendVoicePacket(newData);
                    }
                    else
                    {
                        if (_totalNumSamplesSent > _sampleNumberOfLastMinAmplitudeVoice + _voiceHoldSamples)
                        {
                            _mumbleClient.ReleasePcmArray(newData);
                            continue;
                        }
                        _mumbleClient.SendVoicePacket(newData);
                        // If this is the sample before the hold turns off, stop sending after it's sent
                        if (_totalNumSamplesSent + NumSamplesPerOutgoingPacket > _sampleNumberOfLastMinAmplitudeVoice + _voiceHoldSamples)
                        {
                            _mumbleClient.StopSendingVoice();
                        }
                    }
                }
                else
                {
                    _mumbleClient.SendVoicePacket(newData);
                }
            }
        }
 public void SendVoicePacket(PcmArray floatData)
 {
     _manageSendBuffer.SendVoice(floatData, SpeechTarget.Normal, 0);
 }
예제 #19
0
 public void SendVoice(PcmArray pcm, SpeechTarget target, uint targetId)
 {
     _stopSendingRequested = false;
     _encodingBuffer.Add(pcm, target, targetId);
     _waitHandle.Set();
 }