SafeDispatch/MotoTrbo_GW/AudioManager.cs

246 lines
8.0 KiB
C#
Raw Permalink Normal View History

2024-02-22 16:43:59 +00:00
using NAudio.Wave;
using System;
using System.Collections.Generic;
using static MotoTrbo_GW.radioForm;
namespace MotoTrbo_GW
{
public class AudioManager : IDisposable
{
#region Private Fields
private IWavePlayer _wavePlayer;
private WaveIn _waveIn = null; // I will istantiate this just for waveOut class
#endregion
#region Constructor
/// <summary>
/// Constructor for Asio
/// </summary>
public AudioManager(string driverName)
{
// instantiate asioOut class
InstantiateAsioClass(driverName);
}
/// <summary>
/// Constructor for WaveIn and WaveOut
/// </summary>
/// <param name="outDeviceNumber"></param>
/// <param name="inDeviceNumber"></param>
/// <param name="recordBufferMiliseconds"></param>
/// <param name="recordingWaveFormat"></param>
public AudioManager(int outDeviceNumber, int inDeviceNumber, int recordBufferMiliseconds, WaveFormat recordingWaveFormat)
{
// instantiate waveOut and waveIn classes
InstantiateWaveClasses(outDeviceNumber, inDeviceNumber, recordBufferMiliseconds, recordingWaveFormat);
}
#endregion
#region Public Members
/// <summary>
/// Gets the names of the installed Asio drivers
/// </summary>
/// <returns></returns>
public static string[] GetAsioDriverNames()
{
return AsioOut.GetDriverNames();
}
public List<sDevice> GetAsioInputDevices()
{
if (_wavePlayer is AsioOut)
{
AsioOut asioClass = (AsioOut)_wavePlayer;
List<sDevice> listToReturn = new List<sDevice>();
int nrOfInDevices = asioClass.DriverInputChannelCount;
for (int i = 0; i < nrOfInDevices; i++)
{
listToReturn.Add(new sDevice() { index = i, name = asioClass.AsioInputChannelName(i) });
}
return listToReturn;
}
else
throw new AudioManagerException("Call GetAsioInputDevices() method only for AudioManager created for Asio");
}
public List<sDevice> GetAsioOutputDevices()
{
if (_wavePlayer is AsioOut)
{
AsioOut asioClass = (AsioOut)_wavePlayer;
List<sDevice> listToReturn = new List<sDevice>();
int nrOfOUTDevices = asioClass.DriverOutputChannelCount;
for (int i = 0; i < nrOfOUTDevices; i++)
{
listToReturn.Add(new sDevice() { index = i, name = asioClass.AsioOutputChannelName(i) });
}
return listToReturn;
}
else
throw new AudioManagerException("Call GetAsioOutputDevices() method only for AudioManager created for Asio");
}
public static List<sDevice> GetWaveInputDevices()
{
List<sDevice> listToReturn = new List<sDevice>();
int nrOfWaveInDevices = WaveIn.DeviceCount;
for (int i = 0; i < nrOfWaveInDevices; i++)
{
WaveInCapabilities deviceInfo = WaveIn.GetCapabilities(i);
listToReturn.Add(new sDevice() { index = i, name = deviceInfo.ProductName.Trim() });
}
return listToReturn;
}
public static List<sDevice> GetWaveOutputDevices()
{
List<sDevice> listToReturn = new List<sDevice>();
int nrOfWaveOUTDevices = WaveOut.DeviceCount;
for (int i = 0; i < nrOfWaveOUTDevices; i++)
{
WaveOutCapabilities deviceInfo = WaveOut.GetCapabilities(i);
listToReturn.Add(new sDevice() { index = i, name = deviceInfo.ProductName.Trim() });
}
return listToReturn;
}
public void Play()
{
_wavePlayer.Play();
}
public void Stop()
{
_wavePlayer.Stop();
}
public void WaveInStartRecording()
{
_waveIn?.StartRecording();
}
public void WaveinStopRecording()
{
_waveIn?.StopRecording();
}
public void Init(IWaveProvider waveProvider, int recordChannels = -1, int recordOnlySampleRate = -1)
{
if (_wavePlayer is WaveOut)
{
// Init for WaveOut
((WaveOut)_wavePlayer).Init(waveProvider);
}
else if (_wavePlayer is AsioOut)
{
// Init for AsioOut
if (recordChannels != -1 && recordOnlySampleRate != -1)
((AsioOut)_wavePlayer).InitRecordAndPlayback(waveProvider, recordChannels, recordOnlySampleRate);
}
}
/// <summary>
/// The maximum number of input channels this ASIO driver supports
/// </summary>
public int AsioDriverInputChannelCount
{
get
{
if (_wavePlayer is AsioOut)
return ((AsioOut)_wavePlayer).DriverInputChannelCount;
else
throw new AudioManagerException("Property AsioDriverInputChannelCount can be use only if AudioManager object is constructed for asio");
}
}
public void Dispose()
{
_wavePlayer?.Dispose();
_waveIn?.Dispose();
}
#endregion
#region Private Methods
private int GetDriverIdByName(string driverName)
{
int i = 0;
foreach (var obj in AsioOut.GetDriverNames())
{
if (obj == driverName)
return i;
i++;
}
return 0;
}
private void InstantiateAsioClass(string driverName)
{
//_wavePlayer = new AsioOut(AsioOut.GetDriverNames()[0]);
_wavePlayer = new AsioOut(GetDriverIdByName(driverName));
AsioOut asioClass = (AsioOut)_wavePlayer;
asioClass.AudioAvailable += AsioClass_AudioAvailable;
asioClass.PlaybackStopped += AsioClass_PlaybackStopped;
}
private void AsioClass_PlaybackStopped(object sender, StoppedEventArgs e)
{
PlaybackStopped?.Invoke(this, e);
}
private void AsioClass_AudioAvailable(object sender, AsioAudioAvailableEventArgs e)
{
AsioAudioAvailable?.Invoke(this, e);
}
private void InstantiateWaveClasses(int outDeviceNumber, int inDeviceNumber, int recordBufferMiliseconds, WaveFormat recordingWaveFormat)
{
// Instantiate waveOut
WaveOut waveOutClass = new WaveOut();
waveOutClass.DeviceNumber = outDeviceNumber;
_wavePlayer = waveOutClass;
// Instatiate waveIn
_waveIn = new WaveIn();
_waveIn.DeviceNumber = inDeviceNumber;
_waveIn.BufferMilliseconds = recordBufferMiliseconds;
_waveIn.DataAvailable += WaveIn_DataAvailable;
_waveIn.WaveFormat = recordingWaveFormat;
}
private void WaveIn_DataAvailable(object sender, WaveInEventArgs e)
{
WaveInAudioAvailable?.Invoke(this, e);
}
#endregion
#region Events
public event EventHandler<AsioAudioAvailableEventArgs> AsioAudioAvailable;
public event EventHandler<WaveInEventArgs> WaveInAudioAvailable;
public event EventHandler<StoppedEventArgs> PlaybackStopped;
#endregion
}
[Serializable]
public class AudioManagerException : Exception
{
public AudioManagerException() { }
public AudioManagerException(string message) : base(message) { }
public AudioManagerException(string message, Exception inner) : base(message, inner) { }
protected AudioManagerException(
System.Runtime.Serialization.SerializationInfo info,
System.Runtime.Serialization.StreamingContext context) : base(info, context) { }
}
}