Reputation: 701
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
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
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;
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