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 /// /// Constructor for Asio /// public AudioManager(string driverName) { // instantiate asioOut class InstantiateAsioClass(driverName); } /// /// Constructor for WaveIn and WaveOut /// /// /// /// /// public AudioManager(int outDeviceNumber, int inDeviceNumber, int recordBufferMiliseconds, WaveFormat recordingWaveFormat) { // instantiate waveOut and waveIn classes InstantiateWaveClasses(outDeviceNumber, inDeviceNumber, recordBufferMiliseconds, recordingWaveFormat); } #endregion #region Public Members /// /// Gets the names of the installed Asio drivers /// /// public static string[] GetAsioDriverNames() { return AsioOut.GetDriverNames(); } public List GetAsioInputDevices() { if (_wavePlayer is AsioOut) { AsioOut asioClass = (AsioOut)_wavePlayer; List listToReturn = new List(); 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 GetAsioOutputDevices() { if (_wavePlayer is AsioOut) { AsioOut asioClass = (AsioOut)_wavePlayer; List listToReturn = new List(); 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 GetWaveInputDevices() { List listToReturn = new List(); 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 GetWaveOutputDevices() { List listToReturn = new List(); 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); } } /// /// The maximum number of input channels this ASIO driver supports /// 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 AsioAudioAvailable; public event EventHandler WaveInAudioAvailable; public event EventHandler 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) { } } }