246 lines
8.0 KiB
C#
246 lines
8.0 KiB
C#
|
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) { }
|
|||
|
}
|
|||
|
}
|