/// <summary>
        /// Processes samples data from microphone recording and fills buffer of samples then sends it over network
        /// </summary>
        private void ProcessRecording()
        {
            int currentPosition = CustomMicrophone.GetPosition(_microphoneDevice);

            // fix for end record incorrect position
            if (_stopRecordPosition != -1)
            {
                currentPosition = _stopRecordPosition;
            }

            if (recording || currentPosition != _lastPosition)
            {
                float[] array = new float[Constants.RecordingTime * Constants.SampleRate];
                CustomMicrophone.GetRawData(ref array, _workingClip);

                if (_lastPosition != currentPosition && array.Length > 0)
                {
                    if (_lastPosition > currentPosition)
                    {
                        _buffer.AddRange(GetChunk(array, _lastPosition, array.Length - _lastPosition));
                        _buffer.AddRange(GetChunk(array, 0, currentPosition));
                    }
                    else
                    {
                        _buffer.AddRange(GetChunk(array, _lastPosition, currentPosition - _lastPosition));
                    }

                    // sends data chunky
                    if (_buffer.Count >= Constants.ChunkSize)
                    {
                        SendDataToNetwork(_buffer.GetRange(0, Constants.ChunkSize));
                        _buffer.RemoveRange(0, Constants.ChunkSize);
                    }
                }

                _lastPosition = currentPosition;
            }
            else
            {
                _lastPosition = currentPosition;

                if (_buffer.Count > 0)
                {
                    // sends left data chunky
                    if (_buffer.Count >= Constants.ChunkSize)
                    {
                        SendDataToNetwork(_buffer.GetRange(0, Constants.ChunkSize));
                        _buffer.RemoveRange(0, Constants.ChunkSize);
                    }
                    // sends all left data
                    else
                    {
                        SendDataToNetwork(_buffer);
                        _buffer.Clear();
                    }
                }
            }
        }
    private IEnumerator RecordingHandler()
    {
        //Log.Debug("STT.RecordingHandler()", "devices: {0}", Microphone.devices);
        _recording = CustomMicrophone.Start(_microphoneID, true, _recordingBufferSize, _recordingHZ);

        yield return(null);      // let _recordingRoutine get set..

        if (_recording == null)
        {
            StopRecording();
            yield break;
        }

        bool bFirstBlock = true;
        int  midPoint    = _recording.samples / 2;

        float[] samples = null;

        while (_recordingRoutine != 0 && _recording != null)
        {
            int writePos = CustomMicrophone.GetPosition(_microphoneID);
            if (writePos > _recording.samples || !CustomMicrophone.IsRecording(_microphoneID))
            {
                Log.Error("STT.RecordingHandler()", "Microphone disconnected.");
                StopRecording();
                yield break;
            }

            if ((bFirstBlock && writePos >= midPoint) ||
                (!bFirstBlock && writePos < midPoint))
            {
                // front block is recorded, make a RecordClip and pass it onto our callback.
                samples = new float[midPoint];
                _recording.GetData(samples, bFirstBlock ? 0 : midPoint);

                AudioData record = new AudioData();
                record.MaxLevel = Mathf.Max(Mathf.Abs(Mathf.Min(samples)), Mathf.Max(samples));
                record.Clip     = AudioClip.Create("Recording", midPoint, _recording.channels, _recordingHZ, false);
                record.Clip.SetData(samples, 0);

                _service.OnListen(record);

                bFirstBlock = !bFirstBlock;
            }
            else
            {
                // calculate the number of samples remaining until we ready for a block of audio,
                // and wait that amount of time it will take to record.
                int   remaining     = bFirstBlock ? (midPoint - writePos) : (_recording.samples - writePos);
                float timeRemaining = (float)remaining / (float)_recordingHZ;

                yield return(new WaitForSeconds(timeRemaining));
            }
        }

        yield break;
    }
Beispiel #3
0
    private void UpdateRipples()
    {
        if (!photonView.IsMine)
        {
            return;
        }

        int currentPosition = CustomMicrophone.GetPosition(_microphoneDevice);

        //cheks how many samples were recorder since last time we calculated
        //if it went around the buffer (so past the limit and back to 0) we just
        //do the rest of the array and next time start from 0
        if (currentPosition != _lastPosition)
        {
            int     length = Constants.RecordingTime * Constants.SampleRate;
            float[] data   = new float[length];

            CustomMicrophone.GetRawData(ref data, recorder.AudioClip);

            if (currentPosition > _lastPosition)
            {
                int len = currentPosition - _lastPosition;
                decibelsValue = ComputeDB(data, _lastPosition, ref len);
                _lastPosition = currentPosition;
            }
            else
            {
                int len = data.Length - _lastPosition;
                decibelsValue = ComputeDB(data, _lastPosition, ref len);
                _lastPosition = 0;
            }

            //udpate sound ripples animation on all clients
            photonView.RPC(nameof(UpdateSoundRiples), RpcTarget.All, decibelsValue);

            if (count < 1 / _updateFrequency)
            {
                count++;
                positiveInLastSecond |= decibelsValue > 0;
            }
            else
            {
                count = 1;
                positiveInLastSecond = decibelsValue > 0;
            }
        }
    }
Beispiel #4
0
        /// <summary>
        /// Processes samples data from microphone recording and fills buffer of samples then sends it over network
        /// </summary>
        private void ProcessRecording()
        {
            int currentPosition = CustomMicrophone.GetPosition(_microphoneDevice);

            if (recording || currentPosition != _lastPosition)
            {
                float[] array = new float[Constants.RecordingTime * Constants.SampleRate];
                CustomMicrophone.GetRawData(ref array, _workingClip);

                if (_lastPosition != currentPosition && array.Length > 0)
                {
                    int lastPosition = _lastPosition;
                    _lastPosition = currentPosition;

                    if (lastPosition > _lastPosition)
                    {
                        _buffer.AddRange(array.ToList().GetRange(lastPosition, array.Length - lastPosition));
                        _buffer.AddRange(array.ToList().GetRange(0, _lastPosition));
                    }
                    else
                    {
                        _buffer.AddRange(array.ToList().GetRange(lastPosition, _lastPosition - lastPosition));
                    }
                }

                if (_buffer.Count >= Constants.ChunkSize)
                {
                    SendDataToNetwork(_buffer.GetRange(0, Constants.ChunkSize));
                    _buffer.RemoveRange(0, Constants.ChunkSize);
                }
            }
            else
            {
                if (_buffer.Count > 0)
                {
                    SendDataToNetwork(_buffer);
                    _buffer.Clear();
                }
            }
        }
        /// <summary>
        /// Stops recording of microphone
        /// </summary>
        public void StopRecord()
        {
            if (!CustomMicrophone.IsRecording(_microphoneDevice))
            {
                return;
            }

            recording = false;

            if (CustomMicrophone.HasConnectedMicrophoneDevices())
            {
                _stopRecordPosition = CustomMicrophone.GetPosition(_microphoneDevice);

                CustomMicrophone.End(_microphoneDevice);
            }

            if (_workingClip != null)
            {
                Destroy(_workingClip);
            }

            RecordEndedEvent?.Invoke();
        }
Beispiel #6
0
        public void Update()
        {
            if (IsRecording)
            {
                _currentSamplePosition = CustomMicrophone.GetPosition(MicrophoneDevice);
                CustomMicrophone.GetRawData(ref _currentAudioSamples, _microphoneWorkingAudioClip);

                if (DetectVoice)
                {
                    bool isTalking = _voiceDetectionManager.HasDetectedVoice(AudioClip2ByteConverter.FloatToByte(_currentAudioSamples));

                    if (isTalking)
                    {
                        _endTalkingDelay = 0f;
                    }
                    else
                    {
                        _endTalkingDelay += Time.deltaTime;
                    }

                    if (!_isTalking && isTalking)
                    {
                        _isTalking = true;

#if NET_2_0 || NET_2_0_SUBSET
                        if (TalkBeganEvent != null)
                        {
                            TalkBeganEvent();
                        }
#else
                        TalkBeganEvent?.Invoke();
#endif
                    }
                    else if (_isTalking && !isTalking && _endTalkingDelay >= _speechRecognitionManager.CurrentConfig.voiceDetectionEndTalkingDelay)
                    {
                        _isTalking = false;

                        LastRecordedRaw  = _currentRecordingVoice.ToArray();
                        LastRecordedClip = AudioConvert.Convert(LastRecordedRaw, _microphoneWorkingAudioClip.channels);

                        _currentRecordingVoice.Clear();
#if NET_2_0 || NET_2_0_SUBSET
                        if (TalkEnded != null)
                        {
                            TalkEnded(LatestVoiceAudioClip, LastRecordedRaw);
                        }
#else
                        TalkEndedEvent?.Invoke(LastRecordedClip, LastRecordedRaw);
#endif
                    }
                    else if (_isTalking && isTalking)
                    {
                        AddAudioSamplesIntoBuffer();
                    }
                }
                else
                {
                    AddAudioSamplesIntoBuffer();
                }

                _previousSamplePosition = _currentSamplePosition;
            }
        }
Beispiel #7
0
        private void Update()
        {
            try
            {
                if (CustomMicrophone.IsRecording(string.Empty))
                {
                    float[] array = new float[0];
                    CustomMicrophone.GetRawData(ref array);

                    if (_buffer.position != CustomMicrophone.GetPosition(CustomMicrophone.devices[0]) && array.Length > 0)
                    {
                        int lastPosition = _buffer.position;
                        _buffer.position = CustomMicrophone.GetPosition(CustomMicrophone.devices[0]);

                        if (lastPosition > _buffer.position)
                        {
                            _buffer.data.AddRange(array.ToList().GetRange(lastPosition, array.Length - lastPosition));
                            _buffer.data.AddRange(array.ToList().GetRange(0, _buffer.position));
                        }
                        else
                        {
                            _buffer.data.AddRange(array.ToList().GetRange(lastPosition, _buffer.position - lastPosition));
                        }
                    }

                    _audioClipReadyToUse = _buffer.data.Count >= _sampleRate * _recordingTime;

                    if (_playing)
                    {
                        _delay -= Time.deltaTime;

                        if (_delay <= 0)
                        {
                            _playing = false;
                        }
                    }
                    else
                    {
                        if (_audioClipReadyToUse)
                        {
                            List <float> chunk;

                            if (_buffer.data.Count >= _sampleRate)
                            {
                                chunk = _buffer.data.GetRange(0, _sampleRate);
                                _buffer.data.RemoveRange(0, _sampleRate);
                            }
                            else
                            {
                                chunk = _buffer.data;
                                _buffer.data.Clear();
                                for (int i = chunk.Count; i < _sampleRate; i++)
                                {
                                    chunk.Add(0);
                                }
                            }

                            _audioSource.clip.SetData(chunk.ToArray(), 0);
                            _audioSource.Play();

                            _delay   = _recordingTime;
                            _playing = true;
                        }
                    }
                }
            }
            catch (Exception ex)
            {
                Debug.Log(ex.Message + " | " + ex.StackTrace);
            }
        }
Beispiel #8
0
    private void UpdateRipples()
    {
        if (!photonView.IsMine)
        {
            return;
        }

        if (stopSendingRPC)
        {
            return;
        }

        int currentPosition = CustomMicrophone.GetPosition(_microphoneDevice);

        //cheks how many samples were recorder since last time we calculated
        //if it went around the buffer (so past the limit and back to 0) we just
        //do the rest of the array and next time start from 0
        if (currentPosition != _lastPosition)
        {
            int     length = 1 * 44100;
            float[] data   = new float[length];

            // only works if audioClip is the one where this microphone records
            CustomMicrophone.GetRawData(ref data, voice.SelfAudioClip());

            float newDecibelsValue;
            if (currentPosition > _lastPosition)
            {
                int len = currentPosition - _lastPosition;
                newDecibelsValue = ComputeDB(data, _lastPosition, ref len);
                _lastPosition    = currentPosition;
            }
            else
            {
                int len = data.Length - _lastPosition;
                newDecibelsValue = ComputeDB(data, _lastPosition, ref len);
                _lastPosition    = 0;
            }

            if (walking.isPlaying)
            {
                newDecibelsValue += 5;
            }
            else if (running.isPlaying)
            {
                newDecibelsValue += 15;
            }

            decibelsValue = decibelsMultiplier * newDecibelsValue;

            //udpate sound ripples animation on all clients
            photonView.RPC(nameof(UpdateSoundRiples), RpcTarget.All, decibelsValue);

            if (count < 1 / _updateFrequency)
            {
                count++;
                positiveInLastSecond |= decibelsValue > 0;
            }
            else
            {
                count = 1;
                positiveInLastSecond = decibelsValue > 0;
            }
        }
    }