public int Read(short[] data) { int samples = AvailableSamples; Alc.CaptureSamples(deviceId, bufferPtr, samples); Array.Copy(buffer, data, samples); return(samples); }
public int Read(AudioBuffer audioBuffer) { int samples = AvailableSamples; Alc.CaptureSamples(deviceId, bufferPtr, samples); audioBuffer.Load(buffer, samples, frequency, channels); return(samples); }
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()); }
public short[] Read() { int samples = AvailableSamples; Alc.CaptureSamples(deviceId, bufferPtr, samples); short[] tmpBuffer = new short[samples]; Array.Copy(buffer, tmpBuffer, samples); return(tmpBuffer); }
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); }
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); } }
public void Read <T>(ref T data, int sampleCount) where T : struct { Alc.CaptureSamples(handle, ref data, sampleCount); }