sample-service/Service/VoiceTrackerService.cs
2025-05-13 21:55:57 +03:00

60 lines
2.1 KiB
C#

using System;
using System.Linq;
using Avalonia.Threading;
using NAudio.CoreAudioApi;
using NAudio.Wave;
using SoundTesting;
namespace SoundTester.Service;
public class VoiceTrackerService
{
private WasapiCapture _wasapiCapture;
private WasapiOut _wasapiOut;
private BufferedWaveProvider _bufferedWaveProvider;
private DevicesEnumerator _devicesEnumerator;
private float _volume = -96;
public delegate void DecibelLevelHandler(float level);
public event DecibelLevelHandler? DecibelLevelEvent;
public VoiceTrackerService(string deviceName)
{
var en = new MMDeviceEnumerator(); //Костыль
var inD = en.EnumerateAudioEndPoints(DataFlow.Capture, DeviceState.Active).FirstOrDefault(x => x.FriendlyName == deviceName);
var outD = en.GetDefaultAudioEndpoint(DataFlow.Render, Role.Multimedia);
_wasapiCapture = new WasapiCapture(inD, false, 50);
_wasapiOut = new WasapiOut(outD, AudioClientShareMode.Shared, false, 50);
_wasapiCapture.DataAvailable += OnDataAvailable;
_bufferedWaveProvider = new BufferedWaveProvider(_wasapiCapture?.WaveFormat){ DiscardOnBufferOverflow = true };
_wasapiOut.Init(_bufferedWaveProvider);
}
public void Record()
{
_wasapiCapture.StartRecording();
_wasapiOut.Play();
}
private void OnDataAvailable(object sender, WaveInEventArgs e)
{
float[] samples = new float[e.BytesRecorded / 2];
for (int i = 0; i < e.BytesRecorded; i += 2)
{
short sample = BitConverter.ToInt16(e.Buffer, i);
samples[i / 2] = sample / 32768f;
}
float sum = 0;
for (int i = 0; i < samples.Length; i++)
{
sum += samples[i] * samples[i];
}
float rms = (float)Math.Sqrt(sum / samples.Length);
float res = rms > 0 ? 20 * (float)Math.Log10(rms) : -96;
DecibelLevelEvent?.Invoke(res);
_bufferedWaveProvider.AddSamples(e.Buffer, 0, e.BytesRecorded); //Добавление данных для мониторинга микрофона
}
}