172 lines
4.6 KiB
C#
172 lines
4.6 KiB
C#
using System;
|
|
using System.ComponentModel.DataAnnotations;
|
|
using System.Linq;
|
|
using NAudio.CoreAudioApi;
|
|
using NAudio.Wave;
|
|
using NAudio.Wave.SampleProviders;
|
|
using ReactiveUI;
|
|
|
|
namespace SoundTester.ViewModels;
|
|
|
|
public class OscillatorItemViewModel : ViewModelBase //Осциллятор (генератор волны)
|
|
{
|
|
private WasapiOut _waveOut;
|
|
private SignalGenerator _signalGenerator;
|
|
private ISampleProvider _sampleProvider;
|
|
private SignalGeneratorType _typeRef;
|
|
private int _deviceIndex;
|
|
private float _frequency = 20f;
|
|
private bool _sin = true;
|
|
private bool _square = false;
|
|
private bool _sawtooth = false;
|
|
private bool _triangle = false;
|
|
private bool _noise = false;
|
|
private bool _isPlaying = false;
|
|
private string _itemName;
|
|
private string _groupKey;
|
|
|
|
public int DeviceIndex
|
|
{
|
|
get => _deviceIndex;
|
|
set => this.RaiseAndSetIfChanged(ref _deviceIndex, value);
|
|
}
|
|
|
|
[Range(20, 20000)]
|
|
public float Frequency
|
|
{
|
|
get => _frequency;
|
|
set => this.RaiseAndSetIfChanged(ref _frequency, value);
|
|
}
|
|
|
|
public bool Sin
|
|
{
|
|
get => _sin;
|
|
set => this.RaiseAndSetIfChanged(ref _sin, value);
|
|
}
|
|
|
|
public bool Square
|
|
{
|
|
get => _square;
|
|
set => this.RaiseAndSetIfChanged(ref _square, value);
|
|
}
|
|
|
|
public bool Sawtooth
|
|
{
|
|
get => _sawtooth;
|
|
set => this.RaiseAndSetIfChanged(ref _sawtooth, value);
|
|
}
|
|
|
|
public bool Triangle
|
|
{
|
|
get => _triangle;
|
|
set => this.RaiseAndSetIfChanged(ref _triangle, value);
|
|
}
|
|
|
|
public bool Noise
|
|
{
|
|
get => _noise;
|
|
set => this.RaiseAndSetIfChanged(ref _noise, value);
|
|
}
|
|
|
|
public bool IsPlaying
|
|
{
|
|
get => _isPlaying;
|
|
set => this.RaiseAndSetIfChanged(ref _isPlaying, value);
|
|
}
|
|
|
|
public SignalGeneratorType SGType
|
|
{
|
|
get => SGTypeSelection();
|
|
set => this.RaiseAndSetIfChanged(ref _typeRef, value);
|
|
}
|
|
|
|
public string ItemName
|
|
{
|
|
get => _itemName;
|
|
set => this.RaiseAndSetIfChanged(ref _itemName, value);
|
|
}
|
|
|
|
private SignalGeneratorType SGTypeSelection() //Выбор типа волны в зависимости от булевых знаечний
|
|
{
|
|
if (Square)
|
|
return SignalGeneratorType.Square;
|
|
else if (Sawtooth)
|
|
return SignalGeneratorType.SawTooth;
|
|
else if (Triangle)
|
|
return SignalGeneratorType.Triangle;
|
|
else if (Noise)
|
|
return SignalGeneratorType.White;
|
|
|
|
return SignalGeneratorType.Sin;
|
|
}
|
|
|
|
public WasapiOut WaveOut
|
|
{
|
|
get => _waveOut;
|
|
set => this.RaiseAndSetIfChanged(ref _waveOut, value);
|
|
}
|
|
|
|
public SignalGenerator SignalGenerator1
|
|
{
|
|
get => _signalGenerator;
|
|
set => this.RaiseAndSetIfChanged(ref _signalGenerator, value);
|
|
}
|
|
|
|
public ISampleProvider SampleProvider
|
|
{
|
|
get => _sampleProvider;
|
|
set => this.RaiseAndSetIfChanged(ref _sampleProvider, value);
|
|
}
|
|
|
|
public string GroupKey
|
|
{
|
|
get => _groupKey;
|
|
set => this.RaiseAndSetIfChanged(ref _groupKey, value);
|
|
}
|
|
|
|
private void WaveOutInit(string audioDevice) //Инициализация осциллятора
|
|
{
|
|
var en = new MMDeviceEnumerator(); //костыль
|
|
var outD = en.EnumerateAudioEndPoints(DataFlow.Render, DeviceState.Active).Where(x => x.FriendlyName == audioDevice).FirstOrDefault();
|
|
|
|
WaveOut?.Stop();
|
|
WaveOut?.Dispose();
|
|
WaveOut = new WasapiOut(outD,AudioClientShareMode.Shared, false, 50);
|
|
|
|
SignalGenerator1 = new SignalGenerator();
|
|
SignalGenerator1.Frequency = Frequency;
|
|
SignalGenerator1.Type = SGType;
|
|
SignalGenerator1.Gain = 0.5;
|
|
|
|
SampleProvider = SignalGenerator1.ToMono();
|
|
WaveOut.Init(SampleProvider);
|
|
}
|
|
|
|
public OscillatorItemViewModel() //Конструктор
|
|
{
|
|
}
|
|
|
|
public OscillatorItemViewModel(string audioDevice) //Конструктор
|
|
{
|
|
ItemName = audioDevice;
|
|
GroupKey = KeyGen();
|
|
|
|
this.WhenAnyValue(
|
|
x => x.Frequency,
|
|
x => x.Sin,
|
|
x => x.Square,
|
|
x => x.Sawtooth,
|
|
x => x.Triangle,
|
|
x => x.Noise)
|
|
.Subscribe(x =>
|
|
{
|
|
IsPlaying = false;
|
|
WaveOutInit(audioDevice);
|
|
});
|
|
}
|
|
|
|
private string KeyGen() //Генерация уникального ключа для группы радиокнопок
|
|
{
|
|
return Guid.NewGuid().ToString();
|
|
}
|
|
} |