rur2641
rur2641

Reputation: 701

How to get volume reading with AudioGraph - UWP

I would like to get the volume level with AudioGraph with audio frame output nodes. This post, uwp AudioGraph audio processing, has some good info; but I can't get good readings.

Code:

AudioGraph audioGraph;
AudioDeviceInputNode deviceInputNode;
AudioFrameOutputNode frameOutputNode;

    private async Task InitAudioGraph()
    {
        AudioGraphSettings settings = new AudioGraphSettings(Windows.Media.Render.AudioRenderCategory.Media);

        CreateAudioGraphResult result = await AudioGraph.CreateAsync(settings);
        if (result.Status != AudioGraphCreationStatus.Success)
        {
            Debug.WriteLine("AudioGraph creation error: " + result.Status.ToString());
        }
        audioGraph = result.Graph;
        CreateAudioDeviceInputNodeResult result1 = await audioGraph.CreateDeviceInputNodeAsync(Windows.Media.Capture.MediaCategory.Media);

        if (result1.Status != AudioDeviceNodeCreationStatus.Success)
        {
            // Cannot create device output node
            Debug.WriteLine(result.Status.ToString());
            return;
        }
        deviceInputNode = result1.DeviceInputNode;
        frameOutputNode = audioGraph.CreateFrameOutputNode();
        frameOutputNode.Start();
        audioGraph.QuantumProcessed += AudioGraph_QuantumProcessed;
    }
    private void AudioGraph_QuantumProcessed(AudioGraph sender, object args)
    {
        Debug.WriteLine("event called");
        AudioFrame frame = frameOutputNode.GetFrame();
        ProcessFrameOutput(frame);
    }
    unsafe private void ProcessFrameOutput(AudioFrame frame)
    {
        using (AudioBuffer buffer = frame.LockBuffer(AudioBufferAccessMode.Write))
        using (IMemoryBufferReference reference = buffer.CreateReference())
        {
            byte* dataInBytes;
            uint capacityInBytes;
            float* dataInFloat;

            // Get the buffer from the AudioFrame
            ((IMemoryBufferByteAccess)reference).GetBuffer(out dataInBytes, out capacityInBytes);

            dataInFloat = (float*)dataInBytes;
    }

    [ComImport]
    [Guid("5B0D3235-4DBA-4D44-865E-8F1D0E4FD04D")]
    [InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
        unsafe interface IMemoryBufferByteAccess
    {
        void GetBuffer(out byte* buffer, out uint capacity);
    }

The previous article explains the number of elements in a quantum because of many input channels. But even assuming one channel, if I print the elements, they still don't make sense. Most values are 0 and some are greater than one. Code:

for (int i = 0; i < audioGraph.SamplesPerQuantum; i++)
            Debug.WriteLine(dataInFloat[i]);

Thank you.

Upvotes: 2

Views: 1902

Answers (2)

Gary93730
Gary93730

Reputation: 441

You can get and set volume level using the .OutgoingGain property as shown below.

private static async Task AddFileToSounds(string uri)
    {
        // Load and add resource sound file to memory dictionary for playing

        var soundFile = await StorageFile.GetFileFromApplicationUriAsync(new Uri(uri));
        var fileInputResult = await graph.CreateFileInputNodeAsync(soundFile);

        if (AudioFileNodeCreationStatus.Success == fileInputResult.Status)
        {
            fileInputs.Add(soundFile.Name, fileInputResult.FileInputNode);
            fileInputResult.FileInputNode.Stop();
            // set volume here using outgoing gain, values 0 - 1
            fileInputResult.FileInputNode.OutgoingGain = 0.1;
            // get volume using the same property
            Debug.WriteLine("fileInputResult.FileInputNode.OutgoingGain = "+ fileInputResult.FileInputNode.OutgoingGain);
            fileInputResult.FileInputNode.AddOutgoingConnection(deviceOutput);
        }
    }

Upvotes: 0

Franklin Chen - MSFT
Franklin Chen - MSFT

Reputation: 4923

But even assuming one channel, if I print the elements, they still don't make sense. Most values are 0 and some are greater than one

You need to use the AudioDeviceInputNode.AddOutgoingConnection method to Link the input and output nodes together before starting the audio graph:

deviceInputNode = result1.DeviceInputNode;
frameOutputNode = audioGraph.CreateFrameOutputNode();
deviceInputNode.AddOutgoingConnection(frameOutputNode);
audioGraph.Start();
audioGraph.QuantumProcessed += AudioGraph_QuantumProcessed;

enter image description here

frameOutputNode = audioGraph.CreateFrameOutputNode(); frameOutputNode.Start();

Why did you start the output node? Please Call AudioGraph.Start() method to start audio graph, otherwise the QuantumProcessed event will not be invoked.

Upvotes: 2

Related Questions