none
Use audio output of an application as a virtual audio input device

    Question

  • Hi,

    I first posted this issue here (https://social.technet.microsoft.com/Forums/en-US/b2e1dfa6-c6aa-48ed-90a5-c7f3e1227d97/use-audio-output-of-an-application-as-a-virtual-audio-input-device?forum=win10itprogeneral), but I've been told that I should post it here instead. I don't think there is an issue with my application though.

    I have a Bluetooth Low Energy (BLE) device that stream audio through a custom service and I must be able to use this audio in any Windows application.

    To do that, I developed an UWP application that connects to the BLE device, processes the audio data and outputs them using the AudioGraph API. Then, I used VB-Cable (vb-cable.com) combined with the "App volume and device preferences" from Windows to use the output of my application as an input for other application.

    Unfortunately, this setup doesn't seem to be very stable (sometimes it works as expected, but sometimes, even though the settings are correct, audio from my application is output on wrong output or not at all). It seems that I'm not the only one to experiment with the problem (https://stackoverflow.com/questions/52973464/set-audio-endpoint-devices-application-specific-programmatically). What do you think about this ?

    The BLE device always works as expected (on Ubuntu too). Moreover, I think that the UWP application also actually works as expected (we can always see that it outputs sound even though it isn't output on the correct output device).

    If this setup can't be fixed, what solution would you suggest to achieve this goal ?

    Please, let me know if you need any more information.

    Thanks in advance,
    Best regards,

    M.M.

    Friday, June 7, 2019 8:47 AM

All replies

  • Hi,

    Thank your for reporting this here. Could you please share me a sample about this. Just a minimal, complete and verifiable example will be enough. And also with the repro steps. We need to reproduce this issue first before we dig it deeper. 

    Best regards,

    Roy


    MSDN Community Support
    Please remember to click "Mark as Answer" the responses that resolved your issue, and to click "Unmark as Answer" if not. This can be beneficial to other community members reading this thread. If you have any compliments or complaints to MSDN Support, feel free to contact MSDNFSF@microsoft.com.

    Monday, June 10, 2019 7:38 AM
    Moderator
  • Hi Roy,

    Thanks for your answer.
    I just tried to reproduce the issue with the UWP AudioCreation sample because I'm almost certain that I had the issue with it too, but I didn't succeed to reproduce it (even though I still have the issue with my application...). I'll try again some more and if I can't succeed, then I'll modify my application so that you can test it without my specific Bluetooth device. How can I share my UWP project once it's ready ?
    Thanks again for your help.

    Best regards,
    Mehdi


    • Edited by Mehdi MIGAULT Monday, June 10, 2019 9:32 AM More details
    Monday, June 10, 2019 9:32 AM
  • Hi again Roy,

    I removed everything non audio-related in my application, tweaked it a little so it can still be used and I still have the issue. I can hear the sound from the application, but it isn't output on the expected device.

    using System;
    using System.Diagnostics;
    using System.Runtime.InteropServices;
    using System.Threading.Tasks;
    using Windows.Foundation;
    using Windows.Media;
    using Windows.Media.Audio;
    using Windows.Media.MediaProperties;
    using Windows.Media.Render;
    using Windows.UI.Xaml.Controls;
    
    namespace TestFrameInput
    {
        [ComImport]
        [Guid("5B0D3235-4DBA-4D44-865E-8F1D0E4FD04D")]
        [InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
    
        unsafe interface IMemoryBufferByteAccess
        {
            void GetBuffer(out byte* buffer, out uint capacity);
        }
    
        public sealed partial class MainPage : Page
        {
            private AudioGraph _audio_graph = null;
            private AudioDeviceOutputNode _device_output = null;
            private AudioFrameInputNode _frame_input = null;
    
            private SystemMediaTransportControls _ctrl = null;
    
            public MainPage()
            {
                this.InitializeComponent();
    
                InitialAudioSetup();
            }
    
            #region Audio graph
            private async Task<bool> InitialAudioSetup()
            {
                {
                    AudioGraphSettings audio_settings = new AudioGraphSettings(AudioRenderCategory.Media)
                    {
                        EncodingProperties = AudioEncodingProperties.CreatePcm(16000, 1, 16),
                        DesiredSamplesPerQuantum = 2048,
                        QuantumSizeSelectionMode = QuantumSizeSelectionMode.ClosestToDesired,
                    };
                    CreateAudioGraphResult result = await AudioGraph.CreateAsync(audio_settings);
                    if (result.Status != AudioGraphCreationStatus.Success)
                    {
                        Debug.WriteLine($"AudioGraph Creation Error because {result.Status.ToString()}");
                        return false;
                    }
    
                    _audio_graph = result.Graph;
                }
    
                {
                    CreateAudioDeviceOutputNodeResult result = await _audio_graph.CreateDeviceOutputNodeAsync();
                    if (result.Status != AudioDeviceNodeCreationStatus.Success)
                    {
                        Debug.WriteLine($"Audio Device Output unavailable because {result.Status.ToString()}");
                        return false;
                    }
    
                    _device_output = result.DeviceOutputNode;
                }
    
                {
                    _frame_input = _audio_graph.CreateFrameInputNode(AudioEncodingProperties.CreatePcm(16000, 1, 16));
                    _frame_input.Stop();
                    _frame_input.AddOutgoingConnection(_device_output);
    
                    _frame_input.QuantumStarted += QuantumStarted;
                }
    
                _audio_graph.Start();
    
                {
                    _ctrl = SystemMediaTransportControls.GetForCurrentView();
                    _ctrl.IsPauseEnabled = true;
                    _ctrl.IsPlayEnabled = true;
                    _ctrl.ButtonPressed += ButtonPressed;
                    _ctrl.PlaybackStatus = MediaPlaybackStatus.Paused;
                }
    
                return true;
            }
    
            private void ButtonPressed(SystemMediaTransportControls sender, SystemMediaTransportControlsButtonPressedEventArgs args)
            {
                Debug.WriteLine($"{args.Button} pressed");
    
                switch (args.Button)
                {
                    case SystemMediaTransportControlsButton.Play:
                        _frame_input.Start();
                        _ctrl.PlaybackStatus = MediaPlaybackStatus.Playing;
                        break;
    
                    case SystemMediaTransportControlsButton.Pause:
                        _frame_input.Stop();
                        _ctrl.PlaybackStatus = MediaPlaybackStatus.Paused;
                        break;
    
                    default:
                        break;
                }
            }
    
            private void QuantumStarted(AudioFrameInputNode sender, FrameInputNodeQuantumStartedEventArgs args)
            {
                uint samples_needed = (uint)args.RequiredSamples;
    
                if (samples_needed != 0)
                {
                    AudioFrame audio_data = GenerateAudioData(samples_needed);
                    _frame_input.AddFrame(audio_data);
                }
            }
    
            private const double FREQ = 400;
            private const double AMPL = 32767;
            private double theta = 0;
    
            unsafe private AudioFrame GenerateAudioData(uint samples_needed)
            {
                AudioFrame frame = new AudioFrame(samples_needed * sizeof(short));
    
                using (AudioBuffer buffer = frame.LockBuffer(AudioBufferAccessMode.Write))
                using (IMemoryBufferReference reference = buffer.CreateReference())
                {
                    ((IMemoryBufferByteAccess)reference).GetBuffer(out byte* p_bytes, out uint length);
    
                    short* p_short = (short*)p_bytes;
                    double sampleIncrement = ((FREQ * (Math.PI * 2)) / _audio_graph.EncodingProperties.SampleRate);
    
                    for (int i = 0; i < samples_needed; i++)
                    {
                        p_short[i] = (short)(AMPL * Math.Sin(theta));
                        theta += sampleIncrement;
                    }
                }
    
                return frame;
            }
            #endregion
        }
    }
    

    To reproduce it, install VB-Cable and execute the code above. You can start/stop the sound from the application with the taskbar buttons or the keyboard media keys. You should be able to hear a continuous frequency from you default output device (speaker). Then, you can change the output device for this application to set it to "CABLE Input". The expected behavior is that sound should stop playing from speaker, and start playing in "CABLE Input" output device. Observed behavior is that sound is still output to speaker.

    Settings and observed behavior don't match

    Let me know if anything isn't clear or if you need any more information.

    Thanks again and best regards,
    Mehdi

    Monday, June 10, 2019 2:06 PM
  • Hi,

    I tried to reproduce your problem but I got a different behavior with you. When I first run the app, it works well like pic1

    Then I changed the output device, it works correctly. The speaker stops playing and the cable input start to working. Like this:

    It's it shows two apps at the same time. Then I tried to switch back the output device, choose speaker. The speaker starts to play again and the cable input stops. But it shows wrong in the app volume window. Like this:

    So result shows the function (switching the output device) works correctly. But the app volume windows is displaying a wrong device when switch back to speaker.

    I want to confirm if this is the behavior you are getting.

    Best regards,

    Roy


    MSDN Community Support
    Please remember to click "Mark as Answer" the responses that resolved your issue, and to click "Unmark as Answer" if not. This can be beneficial to other community members reading this thread. If you have any compliments or complaints to MSDN Support, feel free to contact MSDNFSF@microsoft.com.

    Wednesday, June 12, 2019 8:10 AM
    Moderator
  • Hi Roy,

    Thanks for your answer.

    I don't have the same behavior. When I try to change the output device (from Speakers to CABLE Input), it doesn't show a duplicate of the app, and the sound is still played on the speaker (same state as your last screenshot I think).
    What happens for you once you're in the last state you describe ? I understand that you face the same issue that I have (output settings doesn't match what actually happens), but did you find a way to make it work again (click Reset button, set back speaker and then Cable Input again, etc...) ?

    Thanks again,

    Best regards,
    Mehdi

    Thursday, June 13, 2019 9:12 AM
  • Hi,

    In my last state, the media is playing from the speaker but the app volume shows show a wrong device. Yes, the display information doesn't match what is happening. But there is still some difference, the function works well in my side. I haven't done anything special. I just restarted my device after installed Cable. Do you have another device to test with this and does it give the same behavior?

    Best regards,

    Roy


    MSDN Community Support
    Please remember to click "Mark as Answer" the responses that resolved your issue, and to click "Unmark as Answer" if not. This can be beneficial to other community members reading this thread. If you have any compliments or complaints to MSDN Support, feel free to contact MSDNFSF@microsoft.com.

    Friday, June 14, 2019 6:10 AM
    Moderator
  • Hi Roy,

    What do you mean by "the function works well in my side" ? If I understand correctly, you mean that just restarting your computer made it possible again to output the sound of the app to the CABLE Input ? In my case, restarting the computer didn't solve the problem, and neither did uninstalling and reinstalling the application and VB-Cable.

    If by other devices, you mean something equivalent to VB-Cable, then no, I don't have any other solution. However I would gladly try other solution to do what I need if you know of any.

    Thanks again for your help.
    Best regards,
    Mehdi

    Friday, June 14, 2019 7:13 AM
  • Hi,

    >>the function works well in my side

    Sorry for making you confused. What I mean is that whenever I changed the output device from app volume windows, it changes correctly. But the problem is that the display window will show a wrong device even it is not the one I selected.  

    Anyway, I've report this issue to another engineer and she will take a look at this. There might be some time delay. Thank you for your patience.

    Best regards,

    Roy


    MSDN Community Support
    Please remember to click "Mark as Answer" the responses that resolved your issue, and to click "Unmark as Answer" if not. This can be beneficial to other community members reading this thread. If you have any compliments or complaints to MSDN Support, feel free to contact MSDNFSF@microsoft.com.

    Monday, June 17, 2019 6:11 AM
    Moderator
  • Hi Roy,

    No problem and thanks for the explanation.

    Thanks again for your help, I'll be waiting for your feedback.

    Best regards,
    Mehdi

    Monday, June 17, 2019 7:56 AM
  • Hi,

    Thank you for your understanding. I'll come back as soon as I got response from another engineer.

    Best regards,

    Roy


    MSDN Community Support
    Please remember to click "Mark as Answer" the responses that resolved your issue, and to click "Unmark as Answer" if not. This can be beneficial to other community members reading this thread. If you have any compliments or complaints to MSDN Support, feel free to contact MSDNFSF@microsoft.com.

    Tuesday, June 18, 2019 1:33 AM
    Moderator
  • Hi,

    The team needs to talk to you 1:1 directly so that they could get more details. I suggest that you might need to open a support ticket for this. Please contact our paid phone support at MS Support. You will get 1:1 support on that. Please kindly note that your support ticket will be free if it is Microsoft's issue.

    Best regards,

    Roy


    MSDN Community Support
    Please remember to click "Mark as Answer" the responses that resolved your issue, and to click "Unmark as Answer" if not. This can be beneficial to other community members reading this thread. If you have any compliments or complaints to MSDN Support, feel free to contact MSDNFSF@microsoft.com.

    2 hours 2 minutes ago
    Moderator