/// <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 _synthesizer?.Dispose( ); _mediaSourceInputNode?.RemoveOutgoingConnection(_deviceOutputNode); _mediaSourceInputNode?.Dispose( ); _deviceOutputNode?.Dispose( ); _audioGraph?.Dispose( ); } disposedValue = true; } }
// Init the AudioGraph // despite the Aync methods - this will exec synchronously to get the InitPhase only get done when all is available private void InitAudioGraph( ) { LOG.Log("InitAudioGraph: Begin"); if (!_canSpeak) { LOG.Log("InitAudioGraph: Canceled with _canSpeak = false"); return; // cannot even try.. } // MUST WAIT UNTIL all items are created, else one may call Speak too early... // cleanup existing items if (_mediaSourceInputNode != null) { if (_deviceOutputNode != null) { _mediaSourceInputNode.RemoveOutgoingConnection(_deviceOutputNode); } _mediaSourceInputNode.Dispose( ); _mediaSourceInputNode = null; } if (_deviceOutputNode != null) { _deviceOutputNode.Dispose( ); _deviceOutputNode = null; } if (_audioGraph != null) { _audioGraph.Dispose( ); _audioGraph = null; } // Create an AudioGraph AudioGraphSettings settings = new AudioGraphSettings(_renderCat) { PrimaryRenderDevice = null, // If PrimaryRenderDevice is null, the default playback device will be used. }; // We await here the execution without providing an async method ... var resultAG = WindowsRuntimeSystemExtensions.AsTask(AudioGraph.CreateAsync(settings)); resultAG.Wait( ); if (resultAG.Result.Status != AudioGraphCreationStatus.Success) { LOG.LogError($"InitAudioGraph: Failed to create AudioGraph with RenderCategory: {_renderCat}"); LOG.LogError($"InitAudioGraph: AudioGraph creation: {resultAG.Result.Status}, TaskStatus: {resultAG.Status}" + $"\nExtError: {resultAG.Result.ExtendedError}"); _canSpeak = false; return; } _audioGraph = resultAG.Result.Graph; LOG.Log($"InitAudioGraph: AudioGraph: [{_audioGraph.EncodingProperties}]"); // Create a device output node // The output node uses the PrimaryRenderDevice of the audio graph. // We await here the execution without providing an async method ... var resultDO = WindowsRuntimeSystemExtensions.AsTask(_audioGraph.CreateDeviceOutputNodeAsync()); resultDO.Wait( ); if (resultDO.Result.Status != AudioDeviceNodeCreationStatus.Success) { // Cannot create device output node LOG.LogError($"InitAudioGraph: DeviceOutputNode creation: {resultDO.Result.Status}, TaskStatus: {resultDO.Status}" + $"\nExtError: {resultDO.Result.ExtendedError}"); _canSpeak = false; return; } _deviceOutputNode = resultDO.Result.DeviceOutputNode; LOG.Log($"InitAudioGraph: DeviceOutputNode: [{_deviceOutputNode.Device}]"); LOG.Log($"InitAudioGraph: InitAudioGraph-END"); }