none
Input devices and ASIO RRS feed

  • Question

  • I'm trying to build an FX guitar pedal app and can read the output devices, create a graph, add effects and then connect the input node to the output node.

    When I then try and record the guitar with effects in Reason DAW I only get the flat pre efects sound recorded.

    Do I need to select the ASIO driver?

    Friday, February 8, 2019 4:50 PM

All replies

  • Hi - I'm trying to create a Guitar FX app and it works fine when using the RealTek speakers but when I pick the ASIO driver the app creates feedback in a wild loop. I want to use the ASIO driver so I can record into the Reason DAW. Also what are the min and max values for each effect property?

    using System;
    using System.Collections.Generic;
    using System.IO;
    using System.Linq;
    using System.Runtime.InteropServices.WindowsRuntime;
    using System.Threading.Tasks;
    using Windows.Devices.Enumeration;
    using Windows.Foundation;
    using Windows.Foundation.Collections;
    using Windows.Media.Audio;
    using Windows.Media.Capture;
    using Windows.Media.Devices;
    using Windows.Media.MediaProperties;
    using Windows.Media.Render;
    using Windows.Storage;
    using Windows.Storage.Pickers;
    using Windows.UI.Xaml;
    using Windows.UI.Xaml.Controls;
    using Windows.UI.Xaml.Controls.Primitives;
    using Windows.UI.Xaml.Data;
    using Windows.UI.Xaml.Input;
    using Windows.UI.Xaml.Media;
    using Windows.UI.Xaml.Navigation;


    namespace AudioGraphFX
    {
        /// <summary>
        /// An empty page that can be used on its own or navigated to within a Frame.
        /// </summary>
        public sealed partial class MainPage : Page
        {
            public MainPage()
            {
                this.InitializeComponent();
            }

            /// <summary>
            /// //////////// Step 1 - List Output devices ////////////////
            /// </summary>
            private DeviceInformationCollection outputDevices;
            private async Task PopulateDeviceList()
            {
                outputDevicesListBox.Items.Clear();
                outputDevices = await DeviceInformation.FindAllAsync(MediaDevice.GetAudioRenderSelector());
                outputDevicesListBox.Items.Add("-- Pick output device --");
                foreach (var device in outputDevices)
                {
                    outputDevicesListBox.Items.Add(device.Name);
                }
            }

            //button to populate device list
            private async void outputs_Click(object sender, RoutedEventArgs e)
            {
                await PopulateDeviceList();
            }

            /// <summary>
            /// //////////// Step 2 - Create Audio Graph ///////////////////
            /// </summary>

            private AudioGraph graph;
            private AudioDeviceOutputNode deviceOutputNode;
            private AudioDeviceInputNode deviceInputNode;

            private async Task CreateAudioGraph()
            {
                AudioGraphSettings settings = new AudioGraphSettings(AudioRenderCategory.Media);
                settings.QuantumSizeSelectionMode = QuantumSizeSelectionMode.LowestLatency;
                settings.PrimaryRenderDevice = outputDevices[outputDevicesListBox.SelectedIndex - 1];

                textBlock.Text += "Output device = " + settings.PrimaryRenderDevice.Name.ToString() +"\n";

                CreateAudioGraphResult result = await AudioGraph.CreateAsync(settings);
                  graph = result.Graph;
                textBlock.Text += "Graph successfully created!" + "\n";

                // Create a device output node
               CreateAudioDeviceOutputNodeResult deviceOutputNodeResult = await graph.CreateDeviceOutputNodeAsync();
                if (deviceOutputNodeResult.Status != AudioDeviceNodeCreationStatus.Success)
                {
                    // Cannot create device output node
                    textBlock.Text += (String.Format("Audio Device Output unavailable because " + deviceOutputNodeResult.Status.ToString()));
                    return;
                }

                deviceOutputNode = deviceOutputNodeResult.DeviceOutputNode;
     
                textBlock.Text += "Device Output connection successfully created" + "\n";
               
                //  Create a device input node using the default audio input device
                 CreateAudioDeviceInputNodeResult deviceInputNodeResult = await graph.CreateDeviceInputNodeAsync(MediaCategory.Other);
                if (deviceInputNodeResult.Status != AudioDeviceNodeCreationStatus.Success)
                {
                    // Cannot create device input node
                    textBlock.Text += (String.Format("Audio Device Input unavailable because " + deviceInputNodeResult.Status.ToString()));
                    return;
                }

                deviceInputNode = deviceInputNodeResult.DeviceInputNode;
               
        
                textBlock.Text += "Device Input connection successfully created" +"\n";

                // Connect the input node to output node
                 deviceInputNode.AddOutgoingConnection(deviceOutputNode);

                
                // Because we are using lowest latency setting, we need to handle device disconnection errors
                graph.UnrecoverableErrorOccurred += Graph_UnrecoverableErrorOccurred;
     
            }

          
            private async void Graph_UnrecoverableErrorOccurred(AudioGraph sender, AudioGraphUnrecoverableErrorOccurredEventArgs args)
            {
                // Recreate the graph and all nodes when this happens
                await Dispatcher.RunAsync(Windows.UI.Core.CoreDispatcherPriority.Normal, async () =>
                {
                    sender.Dispose();
                    // Re-query for devices
                    await PopulateDeviceList();
                });
            }

            ///button to create audio graph
            private async void createAudioGraphbtn_Click(object sender, RoutedEventArgs e)
            {
                await CreateAudioGraph();

                graph.Start();

                textBlock.Text += String.Format("Graph ready - play away!");

            }


            /// Step 3 Add effects ///////////////
            private EchoEffectDefinition echoEffect;
            private void echoBtn_Click(object sender, RoutedEventArgs e)
            {
                echoEffect = new EchoEffectDefinition(graph);

                echoEffect.WetDryMix = 0.7f;
                echoEffect.Feedback = 0.5f;
                echoEffect.Delay = 500.0f;

                deviceOutputNode.EffectDefinitions.Add(echoEffect);
               
                echoBtn.Background = new SolidColorBrush(Windows.UI.Colors.LightBlue);
            }

            private ReverbEffectDefinition reverbEffect;
            private AudioFileInputNode fileInput;
            private AudioFileOutputNode fileOutputNode;

            private void reverbByn_Click(object sender, RoutedEventArgs e)
            {
                reverbEffect = new ReverbEffectDefinition(graph);

                reverbEffect.WetDryMix = 50;
                reverbEffect.ReflectionsDelay = 0;
                reverbEffect.EarlyDiffusion = 0;
                reverbEffect.ReverbDelay = 0;
                reverbEffect.DecayTime = 0.1;
                reverbEffect.Density = 0;
              
                deviceOutputNode.EffectDefinitions.Add(reverbEffect);

                reverbByn.Background = new SolidColorBrush(Windows.UI.Colors.LightBlue);
            }

           
            private void wetdrySlider_ValueChanged(object sender, RangeBaseValueChangedEventArgs e)
            {
                if (reverbEffect != null)
                {
                    double currentValue = wetdrySlider.Value;
                    // wetdrySlider.Text = "Decay: " + currentValue.ToString() + "  s";
                    reverbEffect.WetDryMix = currentValue;
                }

            }

            //reflections
            private void reflectionsReverb_ValueChanged(object sender, RangeBaseValueChangedEventArgs e)
            {
                if (reverbEffect != null)
                {
                    double currentValue = reflectionsReverb.Value;
                    reverbEffect.ReflectionsDelay  = Convert.ToUInt32(currentValue);
                }
            }

            //decay time
            private void decayTime_ValueChanged(object sender, RangeBaseValueChangedEventArgs e)
            {
                if (reverbEffect != null)
                {
                    double currentValue = decayTime.Value;
                    reverbEffect.DecayTime = currentValue;
                }

            }

            //density
            private void densitySlider_ValueChanged(object sender, RangeBaseValueChangedEventArgs e)
            {
                double currentValue = decayTime.Value;
                reverbEffect.Density = currentValue;

            }

            private void slider_ValueChanged(object sender, RangeBaseValueChangedEventArgs e)
            {
                double currentValue = decayTime.Value;
                reverbEffect.EarlyDiffusion = System.Convert.ToByte(currentValue);
            }

           
            
           
        }
    }

    Sunday, February 10, 2019 2:16 PM
  • Please don't post multiple threads on the same topic. If you don't understand the answer to a previous thread (like Roy's response to you on property values) then ask for clarification in that thread rather than in a new one. If you need more help than you're getting in the forum you can open an assisted support case at http://aka.ms/storesupport and choose Developing Windows 10 UWP apps under Contact us. A UWP media specialist will work directly with you.

    Beyond that:

    • Simplify your code: get things working passthrough before adding effects. That way you'll know if the problem is in your effect code or in the rest of the stream. 
    • Check out the AudioGraph sample at https://github.com/Microsoft/Windows-universal-samples/tree/master/Samples/AudioCreation . It should point you in the right direction. If it has the same problems you're seeing then that may point at a lower level issue.
    • This could be driver behavior. Try with a different driver and clearly identify the one (or ones) that have problems. There are many ASIO drivers.


    Sunday, February 10, 2019 11:28 PM
  • Sorry about the multiple threads...

    I've made some progress by switching to the Line 6 ASIO driver, outside my app, in the PC sound control panel - that has stopped the app feeding back on itself. Yay!

    The flat sound does record using the ASIO driver into the Reason 10 DAW. (Nothing wrong with driver)

    With effects added the output does record using Audaity, which is picking up the Realtek driver, but not in Reason using the ASIO driver. 

    Why doesn't the ASIO output add the effects - do I need a submix node??

    btw - only one of my many ASIO drivers gets picked up by the FindAllAsync(MediaDevice.GetAudioRenderSelector()); line and the code samples you talk about have helped however they focus on recording files and playback.

    Finally it would good to see more tutorials out there for musicans / coders ...maybe...

    Monday, February 11, 2019 10:37 AM