private void Recover() { App.Log("Recover MediaPlayer"); graph.Stop(); try { mainInputNode.Dispose(); } catch (Exception) { } try { subInputNode.Dispose(); } catch (Exception) { } try { outputNode.Dispose(); } catch (Exception) { } mainInputNode = null; subInputNode = null; outputNode = null; mainSong = null; subSong = null; try { graph.Dispose(); } catch (Exception) { } graph = null; Init(); }
private async void MainGraph_QuantumProcessed(AudioGraph sender, object args) { try { this.Position = mainInputNode.Position; if (NextJump != null) { if (NextJump != null && Position >= NextJump.Origin - NextJump.CrossFade && Position <= NextJump.Origin && !IsFading && NextJump.Song == mainSong) { IsFading = true; subInputNode = mainInputNode; subSong = mainSong; mainSong = NextJump.TargetSong ?? NextJump.Song; mainInputNode = await mainSong.Song.CreateNode(graph); mainInputNode.AddOutgoingConnection(outputNode); mainInputNode.StartTime = NextJump.TargetTime - (NextJump.Origin - subInputNode.Position); mainInputNode.OutgoingGain = 0; mainInputNode.Start(); } if (IsFading && subInputNode != null) { var fadePosition = (NextJump.Origin - subInputNode.Position); var fadeTime = NextJump.CrossFade; var percentage = Math.Min(1.0, Math.Max(0.0, fadePosition.TotalSeconds / fadeTime.TotalSeconds)); subInputNode.OutgoingGain = percentage; mainInputNode.OutgoingGain = 1.0 - percentage; } if (Position > NextJump.Origin && IsFading && subInputNode != null) { mainInputNode.OutgoingGain = 1.0; subInputNode.Stop(); subInputNode.RemoveOutgoingConnection(outputNode); subInputNode.Dispose(); subInputNode = null; subSong = null; NextJump = NextJump.NextDefaultJump; IsFading = false; } } } catch (Exception e) { App.Log(e); Recover(); } }
public async Task <bool> SetSourceAsync(StorageFile file) { Stop(); _inputNode?.Dispose(); _inputNode = null; var result = await _audioGraph.CreateFileInputNodeAsync(file); LastStatus = result.Status.ToString(); if (result.Status != AudioFileNodeCreationStatus.Success) { return(false); } lock (this) { try { _inputNode = result.FileInputNode; var invalidDuration = TimeSpan.FromMilliseconds(50); if (_inputNode.Duration < invalidDuration) { return(false); } _inputNode.AddOutgoingConnection(_outputNode); ThresoldDuration = _inputNode.Duration - invalidDuration; _inputNode.EffectDefinitions.Add(CreateEchoEffect()); _inputNode.EffectDefinitions.Add(CreateLimiterEffect()); _inputNode.EffectDefinitions.Add(CreateReverbEffect()); _inputNode.EffectDefinitions.Add(CreateEqualizerEffect()); IsEchoEffectEnabled = IsEchoEffectEnabled; IsReverbEffectEnabled = IsReverbEffectEnabled; IsLimiterEffectEnabled = IsLimiterEffectEnabled; IsEQEffectEnabled = IsEQEffectEnabled; } catch (Exception) { return(false); } } if (AutoPlay) { Play(); } return(true); }
public void Dispose() { WaveformRenderer = null; graph?.Dispose(); fileInputNode?.Dispose(); deviceOutput?.Dispose(); }
async void fileInput_FileCompleted(AudioFileInputNode fileInput, object args) { try { await Dispatcher.RunAsync(Windows.UI.Core.CoreDispatcherPriority.Normal, () => { try { fileInput.Reset(); // Reset the file input node so starting the graph will resume playback from beginning of the file _fileInputs.Remove(fileInput); notifyUser($"Disposing: {fileInput.SourceFile.Name} "); fileInput.Dispose(); /**/ if (_fileInputs.Count() == 0) { _graph.Stop(); notifyUser("All Done!!! "); } } catch (Exception ex) { notifyUser(ex.Message); } }); await Dispatcher.RunAsync(Windows.UI.Core.CoreDispatcherPriority.Normal, () => { notifyUser("End of file reached"); }); } catch (Exception ex) { notifyUser(ex.Message); } }
private async void File_Click(object sender, RoutedEventArgs e) { // If another file is already loaded into the FileInput node if (fileInput != null) { // Release the file and dispose the contents of the node fileInput.Dispose(); // Stop playback since a new file is being loaded. Also reset the button UI if (graphButton.Content.Equals("Stop Graph")) { TogglePlay(); } } FileOpenPicker filePicker = new FileOpenPicker(); filePicker.SuggestedStartLocation = PickerLocationId.MusicLibrary; filePicker.FileTypeFilter.Add(".mp3"); filePicker.FileTypeFilter.Add(".wav"); filePicker.FileTypeFilter.Add(".wma"); filePicker.FileTypeFilter.Add(".m4a"); filePicker.ViewMode = PickerViewMode.Thumbnail; StorageFile file = await filePicker.PickSingleFileAsync(); // File can be null if cancel is hit in the file picker if (file == null) { return; } CreateAudioFileInputNodeResult fileInputResult = await graph.CreateFileInputNodeAsync(file); if (AudioFileNodeCreationStatus.Success != fileInputResult.Status) { // Cannot read input file rootPage.NotifyUser(String.Format("Cannot read input file because {0}", fileInputResult.Status.ToString()), NotifyType.ErrorMessage); return; } fileInput = fileInputResult.FileInputNode; fileInput.AddOutgoingConnection(deviceOutput); fileButton.Background = new SolidColorBrush(Colors.Green); if (fileInput.Duration.TotalSeconds < 3) { // Imported file is too short rootPage.NotifyUser(String.Format("This scenario requires a sound file which is longer than 3 seconds"), NotifyType.ErrorMessage); return; } // Trim the file: set the start time to 3 seconds from the beginning // fileInput.EndTime can be used to trim from the end of file fileInput.StartTime = TimeSpan.FromSeconds(3); // Enable buttons in UI to start graph, loop and change playback speed factor graphButton.IsEnabled = true; loopToggle.IsEnabled = true; playSpeedSlider.IsEnabled = true; }
/// <summary> /// Closes and disposes sound file node /// </summary> /// <param name="sender">Audio file input node</param> /// <param name="args">Arguments</param> private async void FileInputNodeOnFileCompleted(AudioFileInputNode sender, object args) { await Windows.ApplicationModel.Core.CoreApplication.MainView.CoreWindow.Dispatcher.RunAsync(CoreDispatcherPriority.Normal, () => { sender.RemoveOutgoingConnection(_outputNode); sender.FileCompleted -= FileInputNodeOnFileCompleted; sender.Dispose(); }); }
private async void File_Click(object sender, RoutedEventArgs e) { // If another file is already loaded into the FileInput node if (fileInputNode != null) { // Release the file and dispose the contents of the node fileInputNode.Dispose(); // Stop playback since a new file is being loaded. Also reset the button UI if (graphButton.Content.Equals("Stop Graph")) { TogglePlay(); } } FileOpenPicker filePicker = new FileOpenPicker(); filePicker.SuggestedStartLocation = PickerLocationId.MusicLibrary; filePicker.FileTypeFilter.Add(".mp3"); filePicker.FileTypeFilter.Add(".wma"); filePicker.FileTypeFilter.Add(".wav"); filePicker.ViewMode = PickerViewMode.Thumbnail; StorageFile file = await filePicker.PickSingleFileAsync(); // File can be null if cancel is hit in the file picker if (file == null) { return; } CreateAudioFileInputNodeResult fileInputResult = await graph.CreateFileInputNodeAsync(file); if (fileInputResult.Status != AudioFileNodeCreationStatus.Success) { // Error reading the input file rootPage.NotifyUser(String.Format("Can't read input file because {0}", fileInputResult.Status.ToString()), NotifyType.ErrorMessage); return; } // File loaded successfully. Enable these buttons in the UI graphButton.IsEnabled = true; echoEffectToggle.IsEnabled = true; reverbEffectToggle.IsEnabled = true; limiterEffectToggle.IsEnabled = true; eqToggle.IsEnabled = true; fileInputNode = fileInputResult.FileInputNode; fileInputNode.AddOutgoingConnection(deviceOutputNode); rootPage.NotifyUser("Successfully loaded input file", NotifyType.StatusMessage); fileButton.Background = new SolidColorBrush(Colors.Green); // Create the four inbox effects CreateEchoEffect(); CreateReverbEffect(); CreateLimiterEffect(); CreateEqEffect(); }
private async void File1_Click(object sender, RoutedEventArgs e) { // If another file is already loaded into the FileInput node if (fileInputNode1 != null) { // Release the file and dispose the contents of the node fileInputNode1.Dispose(); // Stop playback since a new file is being loaded. Also reset the button UI if (graphButton.Content.Equals("Stop Graph")) { TogglePlay(); } } FileOpenPicker filePicker = new FileOpenPicker(); filePicker.SuggestedStartLocation = PickerLocationId.MusicLibrary; filePicker.FileTypeFilter.Add(".mp3"); filePicker.FileTypeFilter.Add(".wma"); filePicker.FileTypeFilter.Add(".wav"); filePicker.ViewMode = PickerViewMode.Thumbnail; StorageFile file1 = await filePicker.PickSingleFileAsync(); // File can be null if cancel is hit in the file picker if (file1 == null) { return; } CreateAudioFileInputNodeResult fileInputNodeResult = await graph.CreateFileInputNodeAsync(file1); if (fileInputNodeResult.Status != AudioFileNodeCreationStatus.Success) { // Cannot read input file rootPage.NotifyUser(String.Format("Can't read input file1 because {0}", fileInputNodeResult.Status.ToString()), NotifyType.ErrorMessage); return; } fileInputNode1 = fileInputNodeResult.FileInputNode; // Since we are going to play two files simultaneously, set outgoing gain to 0.5 to prevent clipping fileInputNode1.AddOutgoingConnection(submixNode, 0.5); // The graph might already be playing, so set up UI accordingly if (graphButton.Content.Equals("Stop Graph")) { audioPipe1.Fill = new SolidColorBrush(Colors.Blue); } // UI tasks: enable buttons, show status message and change color of the input node box graphButton.IsEnabled = true; echoEffectToggle.IsEnabled = true; rootPage.NotifyUser("Loaded File 1", NotifyType.StatusMessage); fileButton1.Background = new SolidColorBrush(Colors.Green); }
private async void PlayAudioGraph_Click(object sender, RoutedEventArgs e) { // If another file is already loaded into the FileInput node if (fileInput != null) { // Release the file and dispose the contents of the node fileInput.Dispose(); } FileOpenPicker filePicker = new FileOpenPicker(); filePicker.SuggestedStartLocation = PickerLocationId.MusicLibrary; filePicker.FileTypeFilter.Add(".mp3"); filePicker.FileTypeFilter.Add(".wav"); filePicker.FileTypeFilter.Add(".wma"); filePicker.FileTypeFilter.Add(".m4a"); filePicker.ViewMode = PickerViewMode.Thumbnail; StorageFile file = await filePicker.PickSingleFileAsync(); // File can be null if cancel is hit in the file picker if (file == null) { return; } CreateAudioFileInputNodeResult fileInputResult = await graph.CreateFileInputNodeAsync(file); if (AudioFileNodeCreationStatus.Success != fileInputResult.Status) { // Cannot read input file Logging.SingleInstance.LogMessage("Cannot read input file because " + fileInputResult.Status); return; } fileInput = fileInputResult.FileInputNode; if (fileInput.Duration <= TimeSpan.FromSeconds(3)) { // Imported file is too short Logging.SingleInstance.LogMessage("Please pick an audio file which is longer than 3 seconds " + fileInputResult.Status); fileInput.Dispose(); fileInput = null; return; } fileInput.AddOutgoingConnection(deviceOutput); // Trim the file: set the start time to 3 seconds from the beginning // fileInput.EndTime can be used to trim from the end of file fileInput.StartTime = TimeSpan.FromSeconds(3); }
private async Task SelectInputFile() { // If another file is already loaded into the FileInput node if (fileInputNode != null) { // Release the file and dispose the contents of the node fileInputNode.Dispose(); // Stop playback since a new file is being loaded. Also reset the button UI if (graphButton.Content.Equals("Stop Graph")) { TogglePlay(); } } FileOpenPicker filePicker = new FileOpenPicker(); filePicker.SuggestedStartLocation = PickerLocationId.MusicLibrary; filePicker.FileTypeFilter.Add(".mp3"); filePicker.ViewMode = PickerViewMode.Thumbnail; StorageFile file = await filePicker.PickSingleFileAsync(); // File can be null if cancel is hit in the file picker if (file == null) { return; } CreateAudioFileInputNodeResult fileInputNodeResult = await graph.CreateFileInputNodeAsync(file); if (fileInputNodeResult.Status != AudioFileNodeCreationStatus.Success) { // Cannot read file rootPage.NotifyUser(String.Format("Cannot read input file because {0}", fileInputNodeResult.Status.ToString()), NotifyType.ErrorMessage); return; } fileInputNode = fileInputNodeResult.FileInputNode; fileInputNode.AddOutgoingConnection(deviceOutputNode); fileButton.Background = new SolidColorBrush(Colors.Green); // Event Handler for file completion fileInputNode.FileCompleted += FileInput_FileCompleted; // Enable the button to start the graph graphButton.IsEnabled = true; // Create the custom effect and apply to the FileInput node AddCustomEffect(); }
/// <summary> /// Overridable Dispose /// Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged resources. /// </summary> /// <param name="disposing">Disposing flag</param> protected virtual void Dispose(bool disposing) { if (!disposedValue) { if (disposing) { // dispose managed state (managed objects) // cleanup existing items _fileInputNode?.Dispose( ); _deviceOutputNode?.Dispose( ); _audioGraph?.Dispose( ); } disposedValue = true; } }
private bool disposedValue = false; // Dient zur Erkennung redundanter Aufrufe. protected virtual void Dispose(bool disposing) { if (!disposedValue) { if (disposing) { graph.Stop(); outputNode.Dispose(); mainInputNode?.Dispose(); subInputNode?.Dispose(); graph.Dispose(); } disposedValue = true; } }
private async Task SelectInputFile() { if (fileInputNode != null) { fileInputNode.Dispose(); if (graphButton.Content.Equals("Stop Graph")) { TogglePlay(); } } FileOpenPicker filePicker = new FileOpenPicker(); filePicker.SuggestedStartLocation = PickerLocationId.MusicLibrary; filePicker.FileTypeFilter.Add(".mp3"); filePicker.FileTypeFilter.Add(".wav"); filePicker.FileTypeFilter.Add(".wma"); filePicker.FileTypeFilter.Add(".m4a"); filePicker.ViewMode = PickerViewMode.Thumbnail; StorageFile file = await filePicker.PickSingleFileAsync(); if (file == null) { return; } CreateAudioFileInputNodeResult fileInputNodeResult = await graph.CreateFileInputNodeAsync(file); if (fileInputNodeResult.Status != AudioFileNodeCreationStatus.Success) { NotifyUser(String.Format("Cannot read input file because {0}", fileInputNodeResult.Status.ToString()), NotifyType.ErrorMessage); return; } fileInputNode = fileInputNodeResult.FileInputNode; fileInputNode.AddOutgoingConnection(deviceOutputNode); fileButton.Background = new SolidColorBrush(Colors.Green); fileInputNode.FileCompleted += FileInput_FileCompleted; graphButton.IsEnabled = true; AddCustomEffect(); }
public async Task LoadFileAsync(StorageFile file) { CreateAudioFileInputNodeResult fileInputResult = await graph.CreateFileInputNodeAsync(file); if (fileInputResult.Status != AudioFileNodeCreationStatus.Success) { // Cannot read input file //rootPage.NotifyUser(String.Format("Cannot read input file because {0}", fileInputResult.Status.ToString()), NotifyType.ErrorMessage); return; } fileInputNode = fileInputResult.FileInputNode; if (fileInputNode.Duration <= TimeSpan.FromSeconds(3)) { // Imported file is too short //rootPage.NotifyUser("Please pick an audio file which is longer than 3 seconds", NotifyType.ErrorMessage); fileInputNode.Dispose(); fileInputNode = null; return; } fileInputNode.AddOutgoingConnection(deviceOutput); //fileButton.Background = new SolidColorBrush(Colors.Green); // Trim the file: set the start time to 3 seconds from the beginning // fileInput.EndTime can be used to trim from the end of file //fileInput.StartTime = TimeSpan.FromSeconds(3); // Enable buttons in UI to start graph, loop and change playback speed factor //graphButton.IsEnabled = true; //loopToggle.IsEnabled = true; //playSpeedSlider.IsEnabled = true; if (WaveformRenderer != null) { WaveformBridgeDefinition definition = new WaveformBridgeDefinition(); definition.Renderer = WaveformRenderer; fileInputNode.EffectDefinitions.Add(definition); } IsPaused = true; }
public void Dispose() { if (fixNode != null) { fixNode.Dispose(); } if (errorNode != null) { errorNode.Dispose(); } foreach (var node in typingNodes) { if (node != null) { node.Dispose(); } } foreach (var node in spaceNodes) { if (node != null) { node.Dispose(); } } if (backspaceNode != null) { backspaceNode.Dispose(); } if (finishedNode != null) { finishedNode.Dispose(); } if (deviceOutputNode != null) { deviceOutputNode.Dispose(); } if (audioGraph != null) { audioGraph.Dispose(); } GC.SuppressFinalize(this); }
private async void openFile() { // If another file is already loaded into the FileInput node if (fileInput != null) { // Release the file and dispose the contents of the node fileInput.Dispose(); } FileOpenPicker filePicker = new FileOpenPicker(); filePicker.SuggestedStartLocation = PickerLocationId.MusicLibrary; filePicker.FileTypeFilter.Add(".mp3"); filePicker.FileTypeFilter.Add(".wav"); filePicker.FileTypeFilter.Add(".wma"); filePicker.FileTypeFilter.Add(".m4a"); filePicker.ViewMode = PickerViewMode.Thumbnail; // StorageFile file = await filePicker.PickSingleFileAsync(); StorageFile file = await GetPackagedFile(null, "alarm.mp3"); // File can be null if cancel is hit in the file picker if (file == null) { return; } CreateAudioFileInputNodeResult fileInputResult = await graph.CreateFileInputNodeAsync(file); if (AudioFileNodeCreationStatus.Success != fileInputResult.Status) { // Cannot read input file return; } fileInput = fileInputResult.FileInputNode; fileInput.AddOutgoingConnection(deviceOutput); // Trim the file: set the start time to 3 seconds from the beginning // fileInput.EndTime can be used to trim from the end of file fileInput.StartTime = TimeSpan.FromSeconds(0); // MediaPlayer player = MediaPlayer.; }
private async void FirstFileButtonClick(object sender, RoutedEventArgs e) { var fileInputNodeResult = await SelectInputFile(); if (fileInputNodeResult == null) { return; } if (_fileInputNode != null) { _fileInputNode.FileCompleted -= FileInput_FileCompleted; _fileInputNode.Dispose(); } _fileInputNode = fileInputNodeResult.FileInputNode; fileInputNodeResult.FileInputNode.AddOutgoingConnection(_subMixNode); Progress.Minimum = 0; Progress.Maximum = _fileInputNode.Duration.TotalSeconds - 1; DurationLabel.Text = _fileInputNode.Duration.ToString(@"m\m\:s\s"); // Event Handler for file completion _fileInputNode.FileCompleted += FileInput_FileCompleted; }
private async void File1_Click(object sender, RoutedEventArgs e) { // If another file is already loaded into the FileInput node if (fileInputNode1 != null) { // Release the file and dispose the contents of the node fileInputNode1.Dispose(); // Stop playback since a new file is being loaded. Also reset the button UI if (graphButton.Content.Equals("Stop Graph")) { TogglePlay(); } } // Open the project dir on the project var folderPicker = new FolderPicker() { CommitButtonText = "Select", ViewMode = PickerViewMode.List, FileTypeFilter = { ".wav" } }; /* * FileOpenPicker filePicker = new FileOpenPicker(); * filePicker.SuggestedStartLocation = PickerLocationId.MusicLibrary; * filePicker.FileTypeFilter.Add(".mp3"); * filePicker.FileTypeFilter.Add(".wma"); * filePicker.FileTypeFilter.Add(".wav"); * filePicker.ViewMode = PickerViewMode.Thumbnail; * StorageFile file1 = await filePicker.PickSingleFileAsync(); */ var folder = await folderPicker.PickSingleFolderAsync(); // File can be null if cancel is hit in the file picker if (folder == null) { return; } /* * CreateAudioFileInputNodeResult fileInputNodeResult = await graph.CreateFileInputNodeAsync(file1); * if (fileInputNodeResult.Status != AudioFileNodeCreationStatus.Success) * { * // Cannot read input file * rootPage.NotifyUser(String.Format("Can't read input file1 because {0}", fileInputNodeResult.Status.ToString()), NotifyType.ErrorMessage); * return; * } */ string baseName = "Channel 1"; string[] namePieces = baseName.Split(' '); var tmpsm1 = namePieces.Take(namePieces.Length - 1); var files = await folder.GetFilesAsync(CommonFileQuery.DefaultQuery); var filteredFiles = new List <StorageFile>(); foreach (var oneFile in files) { var tmps = oneFile.DisplayName.Split(' '); var tmpsm11 = tmps.Take(tmps.Length - 1); if (oneFile.DisplayName.StartsWith(String.Join(" ", tmpsm11))) { filteredFiles.Add(oneFile); } } var mixLevel = 1.0; // will limit / (float)filteredFiles.Count; foreach (var theFile in filteredFiles) { var inputResult = await graph.CreateFileInputNodeAsync(theFile); inputResult.FileInputNode.LoopCount = null; // loop forever inputResult.FileInputNode.AddOutgoingConnection(submixNode, mixLevel); } // The graph might already be playing, so set up UI accordingly if (graphButton.Content.Equals("Stop Graph")) { audioPipe1.Fill = new SolidColorBrush(Colors.Blue); } // UI tasks: enable buttons, show status message and change color of the input node box graphButton.IsEnabled = true; echoEffectToggle.IsEnabled = false; rootPage.NotifyUser($"Loaded {filteredFiles.Count} Files", NotifyType.StatusMessage); fileButton1.Background = new SolidColorBrush(Colors.Green); PlayDescriptionTextBlock.Text = $"playing {filteredFiles.Count} files into submixer"; }
// Async Speak output of a text private async Task PlayAsyncLow(SoundBite soundBite) { _playing = true; // locks additional calls for Speak until finished talking this bit if (!_canPlay || _audioGraph == null || _deviceOutputNode == null) { LOG.LogError($"PlayAsyncLow: Some items do not exist: cannot play..\n [{_audioGraph}] [{_deviceOutputNode}]"); await EndOfSound( ); return; } // don't reload if the sound is already in use if (soundBite.Melody != _soundInUse?.Melody) { // if a prev. Node exists, remove it if (_fileInputNode != null) { _audioGraph.Stop( ); _fileInputNode.FileCompleted -= _fileInputNode_FileCompleted; _fileInputNode.RemoveOutgoingConnection(_deviceOutputNode); _fileInputNode.Dispose( ); _fileInputNode = null; } // set new sound _sound = _installedSounds.Where(x => x.Melody == soundBite.Melody).FirstOrDefault( ); if (_sound == null) { LOG.LogError($"PlayAsyncLow: Melody has no Audiofile: {soundBite.Melody} - cannot play"); await EndOfSound( ); return; } StorageFile file = await StorageFile.CreateStreamedFileAsync($"{_sound.Id}.{_sound.SType}", StreamedFileWriter, null); // create the InputNode var resultAF = await _audioGraph.CreateFileInputNodeAsync(file); if (resultAF.Status != AudioFileNodeCreationStatus.Success) { LOG.LogError($"PlayAsyncLow: AudioFileNodeCreationStatus creation: {resultAF.Status}" + $"\nExtError: {resultAF.ExtendedError}"); await EndOfSound( ); return; } _fileInputNode = resultAF.FileInputNode; _fileInputNode.FileCompleted += _fileInputNode_FileCompleted; _fileInputNode.AddOutgoingConnection(_deviceOutputNode); _audioGraph.Start( ); _soundInUse = _sound.AsCopy( ); } // we capture problems through Exceptions here - the settings and restrictions seem not complete in the Docs try { // Play it // cannot start after prev end - so set it null and seek to start of file _fileInputNode.StartTime = null; _fileInputNode.EndTime = null; // cannot start after prev end - so set it null _fileInputNode.Seek(new TimeSpan(0)); // have to seek to Start, we cannot assign a StartTime before the current Position // only now we can set any new start and end... (that is not in the documents...) _fileInputNode.StartTime = TimeSpan.FromSeconds(soundBite.Tone * _soundInUse.ToneStep_sec); _fileInputNode.EndTime = _fileInputNode.StartTime + TimeSpan.FromSeconds((soundBite.Duration < 0) ? _soundInUse.ToneDuration_sec : soundBite.Duration); _fileInputNode.OutgoingGain = soundBite.Volume; _fileInputNode.LoopCount = (int)soundBite.Loops; // counts down in the Completed Callback - track completeness there (not in docu...) _fileInputNode.PlaybackSpeedFactor = soundBite.SpeedFact; // Plays in the current Thread - cannot be waited for in the same thread _fileInputNode.Start( ); //_audioGraph.Start( ); } catch (Exception e) { LOG.LogError($"PlayAsyncLow: Sample Setup caused an Exception\n{e.Message}"); await EndOfSound( ); } }