public IWavePlayer CreateDevice(AudioOutput output) { IWavePlayer player = null; switch (output.DeviceType) { case AudioOutputs.AudioDeviceType.Asio: { try { player = new AsioOut(output.DeviceName); } catch (InvalidOperationException e) { throw new InvalidOutputDeviceException(e.Message, output); } break; } case AudioOutputs.AudioDeviceType.WaveOut: { try { WaveOutEvent waveOutput = new WaveOutEvent(); waveOutput.DeviceNumber = output.DeviceNumber; waveOutput.NumberOfBuffers = 2; waveOutput.DesiredLatency = output.ChosenLatency; player = waveOutput; } catch (Exception e) { throw new InvalidOutputDeviceException(e.Message, output); } break; } case AudioOutputs.AudioDeviceType.Wasapi: { try { var device = output.MMDevice; // unfortunately, exclusive mode causes repeating buffer on pause, but shared mode sounds awful. NAJAudio.CoreAudioApi.AudioClientShareMode shareMode = NAJAudio.CoreAudioApi.AudioClientShareMode.Exclusive; int latency = output.ChosenLatency; bool useEventSync = false; WasapiOut wasapiOut = new WasapiOut(device, shareMode, useEventSync, latency); player = wasapiOut; } catch (Exception e) { throw new InvalidOutputDeviceException(e.Message, output); } break; } } return(player); }
//private ISampleProvider CreateInputStream(string fileName) //{ // audioFileReader = new AudioFileReader(fileName); // var sampleChannel = new SampleChannel(audioFileReader, true); // sampleChannel.Volume = 1; // return new VolumeSampleProvider(sampleChannel); //} private void CreateWaveOut(AudioOutput output) { CloseWaveOut(); try { waveOut = CreateDevice(output); waveOut.PlaybackStopped += OnPlaybackStopped; } catch (InvalidOutputDeviceException e) { throw e; } }
void HandleSelectedOutputChangedEvent(object sender, SelectedOutputChangedEventArgs socea) { selectedOutput = socea.SelectedOutput; playerControl.SelectedOutput = selectedOutput; }
public SelectedOutputChangedEventArgs(AudioOutput audioOutput) { output = audioOutput; }
public InvalidOutputDeviceException(string message, AudioOutput output) : base(message) { this.output = output; }
public InvalidOutputDeviceException(AudioOutput output) { this.output = output; }
private void lstAudioDevices_SelectionChanged(object sender, SelectionChangedEventArgs e) { if (lstAudioDevices.SelectedIndex == -1) { chkAcourateAsioVolume.IsChecked = false; chkAcourateAsioVolume.IsEnabled = false; sldrDeviceLatency.IsEnabled = false; return; } currentOutput = (AudioOutput)lstAudioDevices.SelectedItem; if (currentOutput.DeviceType == AudioOutputs.AudioDeviceType.Asio) { sldrDeviceLatency.IsEnabled = false; sldrDeviceLatency.Value = 25; lblChosenLatency.Content = "Not Applicable"; } else { if (currentOutput.ChosenLatency > 0) sldrDeviceLatency.Value = currentOutput.ChosenLatency; else sldrDeviceLatency.Value = 100; sldrDeviceLatency.IsEnabled = true; } SaveSelectedDeviceToSettings(); OnRaiseSelectedOutputChangedEvent(new SelectedOutputChangedEventArgs(currentOutput)); if (IsAcourateAsioVolumeAllowed()) { chkAcourateAsioVolume.IsEnabled = true; } else { chkAcourateAsioVolume.IsChecked = false; chkAcourateAsioVolume.IsEnabled = false; } }
public void Play(string filePath, AudioOutput output) { if (scheduleMemoryPlaySettingsChange) { if (memoryPlay == true) { memoryPlay = false; if (memoryFile != null) { memoryFile.Dispose(); memoryFile = null; } GC.Collect(); } else { memoryPlay = true; } scheduleMemoryPlaySettingsChange = false; } if (memoryPlay) { if (!memoryFileTooBig) { PlayFileFromMemory(filePath, output); return; } else { memoryFileTooBig = false; } } // first check to see if we are playing the same file or are paused. if (waveOut != null) { if (waveOut.PlaybackState == PlaybackState.Playing && filePath.Equals(currentFile)) { //isDriverStopped = false; return; } else if (waveOut.PlaybackState == PlaybackState.Paused) { waveOut.Play(); //playbackTimer.Enabled = true; return; } } if (IsFlacFile(filePath)) { string tempWavName = Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData) + "\\wamp\\temp.wav"; string aheadFileName = Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData) + "\\wamp\\" + filePath.Split('\\').Last().ToLower().Replace(".flac", ".wav"); if (File.Exists(aheadFileName)) { if (File.Exists(tempWavName)) { mixingSampleProvider.RemoveAllMixerInputs(); File.Delete(tempWavName); } File.Move(aheadFileName, tempWavName); filePath = tempWavName; } else { FlacDecoder.DecodeFlacToWav(filePath, tempWavName); filePath = tempWavName; } } if (memoryFile != null) { memoryFile.Dispose(); memoryFile = null; } audioFileReader = new AudioFileReader(filePath); try { bitDepth = audioFileReader.WaveFormat.BitsPerSample; sampleRate = audioFileReader.WaveFormat.SampleRate; } catch (Exception createException) { Console.WriteLine(String.Format("{0}", createException.Message), "Error Loading File"); return; } AutoDisposeFileReader autoDisposeFileReader = new AutoDisposeFileReader(audioFileReader); autoDisposeFileReader.FileReaderFinishedEvent += HandleFileReaderFinishedEvent; if (isVolumeEnabled) { volumeSampleProvider = new VolumeSampleProvider(autoDisposeFileReader); volumeSampleProvider.Volume = currentVolume; } // if we already have an existing output of the same bit depth and sample rate, use it if (waveOut != null && bitDepth == previousBitDepth && sampleRate == previousSampleRate) { if (isVolumeEnabled) { mixingSampleProvider.AddMixerInput(volumeSampleProvider); } else { mixingSampleProvider.AddMixerInput(autoDisposeFileReader); } } else //create a new output { try { CreateWaveOut(output); } catch (InvalidOutputDeviceException e) { audioFileReader.Dispose(); audioFileReader = null; throw e; } mixingSampleProvider = null; mixingSampleProvider = new MixingSampleProvider(audioFileReader.WaveFormat); mixingSampleProvider.ReadFully = true; if (isVolumeEnabled) { mixingSampleProvider.AddMixerInput(volumeSampleProvider); } else { mixingSampleProvider.AddMixerInput(autoDisposeFileReader); } try { waveOut.Init(mixingSampleProvider); } catch (Exception initException) { Console.WriteLine(String.Format("{0}", initException.Message), "Error Initializing Output"); return; } waveOut.Play(); } currentFile = filePath; previousBitDepth = bitDepth; previousSampleRate = sampleRate; //playbackTimer.Enabled = true; }
//public void DecodeMemoryAhead(string filePath) //{ // if ((memoryPlay && !scheduleMemoryPlaySettingsChange) || (!memoryPlay && scheduleMemoryPlaySettingsChange)) // { // try // { // nextMemoryFile = new MemoryReaderNew(filePath); // nextMemoryFile.MemoryFileNewFinishedEvent += HandleFileReaderFinishedEvent; // } // catch (Exception e) // { // nextMemoryFile = null; // GC.Collect(); // Console.WriteLine("next File too large to play in memory: " + e.Message); // } // } //} private void PlayFileFromMemory(string filePath, AudioOutput output) { memoryFileTooBig = false; // first check to see if we are playing the same file or are paused. if (waveOut != null) { if (waveOut.PlaybackState == PlaybackState.Playing && filePath.Equals(currentFile)) { //isDriverStopped = false; return; } else if (waveOut.PlaybackState == PlaybackState.Paused) { waveOut.Play(); //playbackTimer.Enabled = true; return; } } if (IsFlacFile(filePath)) { string tempWavName = Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData) + "\\wamp\\temp.wav"; string aheadFileName = Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData) + "\\wamp\\" + filePath.Split('\\').Last().ToLower().Replace(".flac", ".wav"); if (File.Exists(aheadFileName)) { if (File.Exists(tempWavName)) { mixingSampleProvider.RemoveAllMixerInputs(); File.Delete(tempWavName); } File.Move(aheadFileName, tempWavName); filePath = tempWavName; } else { FlacDecoder.DecodeFlacToWav(filePath, tempWavName); filePath = tempWavName; } } if (memoryFile != null) { memoryFile.Dispose(); memoryFile = null; } GC.Collect(); try { memoryFile = new MemoryReaderNew(filePath); memoryFile.MemoryFileNewFinishedEvent += HandleFileReaderFinishedEvent; } catch (Exception e) { memoryFileTooBig = true; memoryFile = null; GC.Collect(); Console.WriteLine("File to large to play in memory: " + e.Message); Play(filePath, output); } try { bitDepth = memoryFile.WaveFormat.BitsPerSample; sampleRate = memoryFile.WaveFormat.SampleRate; } catch (Exception createException) { Console.WriteLine(String.Format("{0}", createException.Message), "Error Loading File"); return; } //MemoryFileSampleProvider memorySampleProvider = new MemoryFileSampleProvider(memoryFile); if (isVolumeEnabled) { //volumeSampleProvider = new VolumeSampleProvider(memorySampleProvider); volumeSampleProvider = new VolumeSampleProvider(memoryFile); volumeSampleProvider.Volume = currentVolume; } // if we already have an existing output of the same bit depth and sample rate, use it if (waveOut != null && bitDepth == previousBitDepth && sampleRate == previousSampleRate) { if (isVolumeEnabled) mixingSampleProvider.AddMixerInput(volumeSampleProvider); else mixingSampleProvider.AddMixerInput((ISampleProvider)memoryFile); } else //create a new output { mixingSampleProvider = null; mixingSampleProvider = new MixingSampleProvider(memoryFile.WaveFormat); mixingSampleProvider.ReadFully = true; //mixingSampleProvider.ReadFully = false; if (isVolumeEnabled) mixingSampleProvider.AddMixerInput(volumeSampleProvider); else //mixingSampleProvider.AddMixerInput(memoryFile.MemorySampleProvider); mixingSampleProvider.AddMixerInput((ISampleProvider)memoryFile); try { CreateWaveOut(output); waveOut.Init(mixingSampleProvider); } catch (Exception initException) { Console.WriteLine(String.Format("{0}", initException.Message), "Error Initializing Output"); return; } waveOut.Play(); } currentFile = filePath; previousBitDepth = bitDepth; previousSampleRate = sampleRate; }
public IWavePlayer CreateDevice(AudioOutput output) { IWavePlayer player = null; switch (output.DeviceType) { case AudioOutputs.AudioDeviceType.Asio: { try { player = new AsioOut(output.DeviceName); } catch (InvalidOperationException e) { throw new InvalidOutputDeviceException(e.Message, output); } break; } case AudioOutputs.AudioDeviceType.WaveOut: { try { WaveOutEvent waveOutput = new WaveOutEvent(); waveOutput.DeviceNumber = output.DeviceNumber; waveOutput.NumberOfBuffers = 2; waveOutput.DesiredLatency = output.ChosenLatency; player = waveOutput; } catch (Exception e) { throw new InvalidOutputDeviceException(e.Message, output); } break; } case AudioOutputs.AudioDeviceType.Wasapi: { try { var device = output.MMDevice; // unfortunately, exclusive mode causes repeating buffer on pause, but shared mode sounds awful. NAJAudio.CoreAudioApi.AudioClientShareMode shareMode = NAJAudio.CoreAudioApi.AudioClientShareMode.Exclusive; int latency = output.ChosenLatency; bool useEventSync = false; WasapiOut wasapiOut = new WasapiOut(device, shareMode, useEventSync, latency); player = wasapiOut; } catch (Exception e) { throw new InvalidOutputDeviceException(e.Message, output); } break; } } return player; }