Beispiel #1
0
        public int Read(short[] data)
        {
            int samples = AvailableSamples;

            Alc.CaptureSamples(deviceId, bufferPtr, samples);
            Array.Copy(buffer, data, samples);
            return(samples);
        }
Beispiel #2
0
        public int Read(AudioBuffer audioBuffer)
        {
            int samples = AvailableSamples;

            Alc.CaptureSamples(deviceId, bufferPtr, samples);
            audioBuffer.Load(buffer, samples, frequency, channels);
            return(samples);
        }
Beispiel #3
0
        private unsafe static short[] captureSamples(IntPtr captureDevice, int frequency, int sampleCount)
        {
            short[] samples      = new short[sampleCount];
            int     samplesTaken = 0;

            bool   isRecording = false;
            double?previousRMS = null;

            short[] buffer = new short[frequency];
            fixed(int *samplesAvailable = new int[1])
            fixed(short *bufferPointer = buffer)
            {
                while (samplesTaken < sampleCount)
                {
                    IntPtr samplesAvailablePointer = new IntPtr((void *)samplesAvailable);
                    Alc.GetIntegerv(captureDevice, Alc.EnumCaptureSamples, 1, samplesAvailablePointer);
                    int       samplesAvailableCount = samplesAvailable[0];
                    const int captureCount          = 2048;
                    if (samplesAvailableCount > captureCount)
                    {
                        Alc.CaptureSamples(captureDevice, (void *)bufferPointer, samplesAvailableCount);

                        // TODO: ... do something with the buffer
                        double rms = calculateRMS(buffer, samplesAvailableCount);

                        double maxAmplitude = short.MaxValue;
                        double intensity    = rms / maxAmplitude;
                        printIntensity(intensity);

                        // compare current rms with previous values to find beginning of a keyword
                        const double factor = 10;
                        if (rms > previousRMS * factor)                         // beginning of window
                        {
                            isRecording = true;
                            //Console.Beep(10000, 10);
                        }

                        if (isRecording)
                        {
                            for (int i = 0; i < samplesAvailableCount; i++)
                            {
                                samples[samplesTaken++] = buffer[i];
                                if (samplesTaken == sampleCount)
                                {
                                    goto done;
                                }
                            }
                        }

                        previousRMS = rms;
                    }
                }
            }
done:
            resetConsoleSettings();

            return(samples.ToArray());
        }
Beispiel #4
0
        public short[] Read()
        {
            int samples = AvailableSamples;

            Alc.CaptureSamples(deviceId, bufferPtr, samples);
            short[] tmpBuffer = new short[samples];
            Array.Copy(buffer, tmpBuffer, samples);
            return(tmpBuffer);
        }
Beispiel #5
0
        private void FillBuffer()
        {
            if (overrideSound != null)
            {
                int totalSampleCount = 0;
                while (totalSampleCount < VoipConfig.BUFFER_SIZE)
                {
                    int sampleCount = overrideSound.FillStreamBuffer(overridePos, overrideBuf);
                    overridePos += sampleCount * 2;
                    Array.Copy(overrideBuf, 0, uncompressedBuffer, totalSampleCount, sampleCount);
                    totalSampleCount += sampleCount;

                    if (sampleCount == 0)
                    {
                        overridePos = 0;
                    }
                }
                int sleepMs = VoipConfig.BUFFER_SIZE * 800 / VoipConfig.FREQUENCY;
                Thread.Sleep(sleepMs - 1);
            }
            else
            {
                int sampleCount = 0;

                while (sampleCount < VoipConfig.BUFFER_SIZE)
                {
                    Alc.GetInteger(captureDevice, Alc.EnumCaptureSamples, out sampleCount);

                    int alcError = Alc.GetError(captureDevice);
                    if (alcError != Alc.NoError)
                    {
                        throw new Exception("Failed to determine sample count: " + alcError.ToString());
                    }

                    if (sampleCount < VoipConfig.BUFFER_SIZE)
                    {
                        int sleepMs = (VoipConfig.BUFFER_SIZE - sampleCount) * 800 / VoipConfig.FREQUENCY;
                        if (sleepMs >= 1)
                        {
                            Thread.Sleep(sleepMs);
                        }
                    }

                    if (!capturing)
                    {
                        return;
                    }
                }

                Alc.CaptureSamples(captureDevice, nativeBuffer, VoipConfig.BUFFER_SIZE);
                Marshal.Copy(nativeBuffer, uncompressedBuffer, 0, uncompressedBuffer.Length);
            }
        }
        internal int PlatformGetData(byte[] buffer, int offset, int count)
        {
            int sampleCount = GetQueuedSampleCount();

            sampleCount = Math.Min(count / 2, sampleCount); // 16bit adjust

            if (sampleCount > 0)
            {
                GCHandle handle = GCHandle.Alloc(buffer, GCHandleType.Pinned);
                Alc.CaptureSamples(_captureDevice, handle.AddrOfPinnedObject() + offset, sampleCount);
                handle.Free();

                CheckALCError("Failed to capture samples.");

                return(sampleCount * 2); // 16bit adjust
            }

            return(0);
        }
        private void UpdateCapture()
        {
            Array.Copy(uncompressedBuffer, 0, prevUncompressedBuffer, 0, VoipConfig.BUFFER_SIZE);
            Array.Clear(uncompressedBuffer, 0, VoipConfig.BUFFER_SIZE);
            while (capturing && !Disconnected)
            {
                int alcError;

                if (CanDetectDisconnect)
                {
                    Alc.GetInteger(captureDevice, Alc.EnumConnected, out int isConnected);
                    alcError = Alc.GetError(captureDevice);
                    if (alcError != Alc.NoError)
                    {
                        throw new Exception("Failed to determine if capture device is connected: " + alcError.ToString());
                    }

                    if (isConnected == 0)
                    {
                        DebugConsole.ThrowError("Capture device has been disconnected. You can select another available device in the settings.");
                        Disconnected = true;
                        break;
                    }
                }

                Alc.GetInteger(captureDevice, Alc.EnumCaptureSamples, out int sampleCount);

                alcError = Alc.GetError(captureDevice);
                if (alcError != Alc.NoError)
                {
                    throw new Exception("Failed to determine sample count: " + alcError.ToString());
                }

                if (sampleCount < VoipConfig.BUFFER_SIZE)
                {
                    int sleepMs = (VoipConfig.BUFFER_SIZE - sampleCount) * 800 / VoipConfig.FREQUENCY;
                    if (sleepMs < 5)
                    {
                        sleepMs = 5;
                    }
                    Thread.Sleep(sleepMs);
                    continue;
                }

                GCHandle handle = GCHandle.Alloc(uncompressedBuffer, GCHandleType.Pinned);
                try
                {
                    Alc.CaptureSamples(captureDevice, handle.AddrOfPinnedObject(), VoipConfig.BUFFER_SIZE);
                }
                finally
                {
                    handle.Free();
                }

                alcError = Alc.GetError(captureDevice);
                if (alcError != Alc.NoError)
                {
                    throw new Exception("Failed to capture samples: " + alcError.ToString());
                }

                double maxAmplitude = 0.0f;
                for (int i = 0; i < VoipConfig.BUFFER_SIZE; i++)
                {
                    uncompressedBuffer[i] = (short)MathHelper.Clamp((uncompressedBuffer[i] * Gain), -short.MaxValue, short.MaxValue);
                    double sampleVal = uncompressedBuffer[i] / (double)short.MaxValue;
                    maxAmplitude = Math.Max(maxAmplitude, Math.Abs(sampleVal));
                }
                double dB = Math.Min(20 * Math.Log10(maxAmplitude), 0.0);

                LastdB        = dB;
                LastAmplitude = maxAmplitude;

                bool allowEnqueue = false;
                if (GameMain.WindowActive)
                {
                    ForceLocal = captureTimer > 0 ? ForceLocal : false;
                    bool pttDown = false;
                    if ((PlayerInput.KeyDown(InputType.Voice) || PlayerInput.KeyDown(InputType.LocalVoice)) &&
                        GUI.KeyboardDispatcher.Subscriber == null)
                    {
                        pttDown = true;
                        if (PlayerInput.KeyDown(InputType.LocalVoice))
                        {
                            ForceLocal = true;
                        }
                        else
                        {
                            ForceLocal = false;
                        }
                    }
                    if (GameMain.Config.VoiceSetting == GameSettings.VoiceMode.Activity)
                    {
                        if (dB > GameMain.Config.NoiseGateThreshold)
                        {
                            allowEnqueue = true;
                        }
                    }
                    else if (GameMain.Config.VoiceSetting == GameSettings.VoiceMode.PushToTalk)
                    {
                        if (pttDown)
                        {
                            allowEnqueue = true;
                        }
                    }
                }

                if (allowEnqueue || captureTimer > 0)
                {
                    LastEnqueueAudio = DateTime.Now;
                    if (GameMain.Client?.Character != null)
                    {
                        var messageType = !ForceLocal && ChatMessage.CanUseRadio(GameMain.Client.Character, out _) ? ChatMessageType.Radio : ChatMessageType.Default;
                        GameMain.Client.Character.ShowSpeechBubble(1.25f, ChatMessage.MessageColor[(int)messageType]);
                    }
                    //encode audio and enqueue it
                    lock (buffers)
                    {
                        if (!prevCaptured) //enqueue the previous buffer if not sent to avoid cutoff
                        {
                            int compressedCountPrev = VoipConfig.Encoder.Encode(prevUncompressedBuffer, 0, VoipConfig.BUFFER_SIZE, BufferToQueue, 0, VoipConfig.MAX_COMPRESSED_SIZE);
                            EnqueueBuffer(compressedCountPrev);
                        }
                        int compressedCount = VoipConfig.Encoder.Encode(uncompressedBuffer, 0, VoipConfig.BUFFER_SIZE, BufferToQueue, 0, VoipConfig.MAX_COMPRESSED_SIZE);
                        EnqueueBuffer(compressedCount);
                    }
                    captureTimer -= (VoipConfig.BUFFER_SIZE * 1000) / VoipConfig.FREQUENCY;
                    if (allowEnqueue)
                    {
                        captureTimer = GameMain.Config.VoiceChatCutoffPrevention;
                    }
                    prevCaptured = true;
                }
                else
                {
                    captureTimer = 0;
                    prevCaptured = false;
                    //enqueue silence
                    lock (buffers)
                    {
                        EnqueueBuffer(0);
                    }
                }

                Thread.Sleep(10);
            }
        }
 /// <summary>Fills the specified buffer with samples from the internal capture ring-buffer. This method does not block: it is an error to specify a sampleCount larger than AvailableSamples.</summary>
 /// <param name="buffer">A pointer to a previously initialized and pinned array.</param>
 /// <param name="sampleCount">The number of samples to be written to the buffer.</param>
 public void ReadSamples(IntPtr buffer, int sampleCount)
 {
     Alc.CaptureSamples(Handle, buffer, sampleCount);
 }
Beispiel #9
0
        void UpdateCapture()
        {
            short[] uncompressedBuffer = new short[VoipConfig.BUFFER_SIZE];
            while (capturing)
            {
                int alcError;
                Alc.GetInteger(captureDevice, Alc.EnumCaptureSamples, out int sampleCount);

                alcError = Alc.GetError(captureDevice);
                if (alcError != Alc.NoError)
                {
                    throw new Exception("Failed to determine sample count: " + alcError.ToString());
                }

                if (sampleCount < VoipConfig.BUFFER_SIZE)
                {
                    int sleepMs = (VoipConfig.BUFFER_SIZE - sampleCount) * 800 / VoipConfig.FREQUENCY;
                    if (sleepMs < 5)
                    {
                        sleepMs = 5;
                    }
                    Thread.Sleep(sleepMs);
                    continue;
                }

                GCHandle handle = GCHandle.Alloc(uncompressedBuffer, GCHandleType.Pinned);
                try
                {
                    Alc.CaptureSamples(captureDevice, handle.AddrOfPinnedObject(), VoipConfig.BUFFER_SIZE);
                }
                finally
                {
                    handle.Free();
                }

                alcError = Alc.GetError(captureDevice);
                if (alcError != Alc.NoError)
                {
                    throw new Exception("Failed to capture samples: " + alcError.ToString());
                }

                double maxAmplitude = 0.0f;
                for (int i = 0; i < VoipConfig.BUFFER_SIZE; i++)
                {
                    uncompressedBuffer[i] = (short)MathHelper.Clamp((uncompressedBuffer[i] * Gain), -short.MaxValue, short.MaxValue);
                    double sampleVal = uncompressedBuffer[i] / (double)short.MaxValue;
                    maxAmplitude = Math.Max(maxAmplitude, Math.Abs(sampleVal));
                }
                double dB = Math.Min(20 * Math.Log10(maxAmplitude), 0.0);

                LastdB = dB;

                bool allowEnqueue = false;
                if (GameMain.WindowActive)
                {
                    if (GameMain.Config.VoiceSetting == GameSettings.VoiceMode.Activity)
                    {
                        if (dB > GameMain.Config.NoiseGateThreshold)
                        {
                            allowEnqueue = true;
                        }
                    }
                    else if (GameMain.Config.VoiceSetting == GameSettings.VoiceMode.PushToTalk)
                    {
                        if (PlayerInput.KeyDown(InputType.Voice) && GUI.KeyboardDispatcher.Subscriber == null)
                        {
                            allowEnqueue = true;
                        }
                    }
                }

                if (allowEnqueue)
                {
                    LastEnqueueAudio = DateTime.Now;
                    //encode audio and enqueue it
                    lock (buffers)
                    {
                        int compressedCount = VoipConfig.Encoder.Encode(uncompressedBuffer, 0, VoipConfig.BUFFER_SIZE, BufferToQueue, 0, VoipConfig.MAX_COMPRESSED_SIZE);
                        EnqueueBuffer(compressedCount);
                    }
                }
                else
                {
                    //enqueue silence
                    lock (buffers)
                    {
                        EnqueueBuffer(0);
                    }
                }

                Thread.Sleep(10);
            }
        }
Beispiel #10
0
 public void Read <T>(ref T data, int sampleCount) where T : struct
 {
     Alc.CaptureSamples(handle, ref data, sampleCount);
 }