简体   繁体   English

UWP AudioGraph API - FrameOutputNode 读取字节错误

[英]UWP AudioGraph API - FrameOutputNode read bytes wrong

I have a problem with the FrameOutputNode of the UWP Audio Graph API.我对 UWP 音频图 API 的FrameOutputNode有问题。 I have a very simple graph that reads audio from a wav (PCM 16000Hz, 16 bit mono) file and sends it to the frame output node for processing.我有一个非常简单的图表,它从 wav(PCM 16000Hz,16 位单声道)文件中读取音频并将其发送到帧 output 节点进行处理。 When processing, I need the audio to be in shorts (as they are in the raw bytes of the file).处理时,我需要音频短(因为它们在文件的原始字节中)。 But as I read here the data can only be read as floats.但是当我在这里阅读时,数据只能作为浮点数读取。

Here is my code:这是我的代码:

var encoding = MediaEncodingProfile.CreateWav(AudioEncodingQuality.Low);
encoding.Audio = AudioEncodingProperties.CreatePcm(16000, 1, 16);

AudioGraphSettings settings = new AudioGraphSettings(AudioRenderCategory.Media);
settings.EncodingProperties = encoding.Audio;
CreateAudioGraphResult result = await AudioGraph.CreateAsync(settings);
var graph = result.Graph;

var localFolder = Windows.Storage.ApplicationData.Current.LocalFolder;
StorageFile file = await localFolder.GetFileAsync("audio.wav");

var fileInputNodeResult = await graph.CreateFileInputNodeAsync(file);
var fileInputNode = fileInputNodeResult.FileInputNode;

fileInputNode.FileCompleted += async (AudioFileInputNode sender, object args) =>
{
    graph.Stop();
}

frameOutputNode = graph.CreateFrameOutputNode(encoding.Audio);
fileInputNode.AddOutgoingConnection(frameOutputNode);

graph.QuantumStarted+= AudioGraph_QuantumStarted;

With the following AudioGraph_QuantumStarted event handler:使用以下AudioGraph_QuantumStarted事件处理程序:

private void AudioGraph_QuantumStarted(AudioGraph sender, object args)
{
    AudioFrame frame = frameOutputNode.GetFrame();
    ProcessFrameOutput(frame);
}

unsafe private void ProcessFrameOutput(AudioFrame frame)
{
    AudioBuffer buffer = frame.LockBuffer(AudioBufferAccessMode.Read);
    IMemoryBufferReference reference = buffer.CreateReference();
    ((IMemoryBufferByteAccess)reference).GetBuffer(out byte* dataInBytes, out uint capacityInBytes);

    if (capacityInBytes > 0) {
        // Read the first 20 bytes 
        for (int i = 0; i < 20; i++)
        {
            Debug.WriteLine(dataInBytes[i]);
        }
    }
}

The bytes I receive in the output are the following.我在 output 中收到的字节如下。 Since the samples are returned as bytes of a float, I marked the sample boundary with a line.由于样本以浮点字节的形式返回,因此我用一条线标记了样本边界。

0 0 0 0 | 0 0 0 184 | 0 0 128 184 | 0 0 0 184 ...

But when I read the actual bytes from the file with a byte reader:但是当我使用字节阅读器从文件中读取实际字节时:

FileStream fIn = new FileStream(@"/path/to/audio.wav", FileMode.Open);
BinaryReader br = new BinaryReader(fIn);
// Skip the first 44 bytes since they are header stuff
br.ReadBytes(44);
for (int i = 0; i < 20; i++) 
{
    Debug.WriteLine(br.ReadByte());
}

Then I get the actual bytes:然后我得到实际的字节:

0 0 | 255 255 | 254 255 | 255 255 | 255 255 | 254 255 | 253 255 | 252 255 ...

Again I marked the individual samples (shorts -> two bytes) with a line.我再次用一条线标记了单个样本(短裤-> 两个字节)。

As you can see the short bytes 255 255 somehow map to float bytes 0 0 0 184 as they reoccur.如您所见,短字节 255 255 以某种方式 map 在再次出现时浮动字节 0 0 0 184。 So what is that mapping?那么这个映射是什么? How can I retrieve the raw shorts from the floats?我怎样才能从花车上取回原始短裤? What do I need to do to actually read the wav file bytes?我需要做什么才能实际读取 wav 文件字节?

My question was answered here .我的问题在这里得到了回答。 Basically, the floats are the range of the shorts -32768 to 32767 converted to range -1 to 1 in float.基本上,浮点数是从 -32768 到 32767 转换为浮点数范围 -1 到 1 的范围。

So given a float x in the buffer (use (float*)dataInFloats = (float*)dataInBytes to convert) you can calculate the corresponding short with:因此,给定缓冲区中的浮点 x (使用(float*)dataInFloats = (float*)dataInBytes进行转换),您可以计算相应的短:

f(x) = (65535 * x - 1) / 2

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM