[UWP] [C#]使用AudioBuffer清理非托管内存。 [英] [UWP][C#]Cleaning up Unmanaged memory from using an AudioBuffer.

查看:103
本文介绍了[UWP] [C#]使用AudioBuffer清理非托管内存。的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

& https:// docs上的AudioGraph文档.microsoft.com / zh-CN / windows / uwp / audio-video-camera / audio-graphs 表示访问音频数据不安全,
需要非托管内存访问,如下面的示例代码所示: / p>

The AudioGraph documentation at https://docs.microsoft.com/en-us/windows/uwp/audio-video-camera/audio-graphs indicates that accessing audio data is unsafe and requires unmanaged memory access as with the following sample code:

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

private double audioWaveTheta = 0;

unsafe private AudioFrame GenerateAudioData(uint samples)
{
    // Buffer size is (number of samples) * (size of each sample)
    // We choose to generate single channel (mono) audio. For multi-channel, multiply by number of channels
    uint bufferSize = samples * sizeof(float);
    AudioFrame frame = new Windows.Media.AudioFrame(bufferSize);

    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);

        // Cast to float since the data we are generating is float
        dataInFloat = (float*)dataInBytes;

        float freq = 1000; // choosing to generate frequency of 1kHz
        float amplitude = 0.3f;
        int sampleRate = (int)audioGraph.EncodingProperties.SampleRate;
        double sampleIncrement = (freq * (Math.PI * 2)) / sampleRate;

        // Generate a 1kHz sine wave and populate the values in the memory buffer
        for (int i = 0; i < samples; i++)
        {
            double sinValue = amplitude * Math.Sin(audioWaveTheta);
            dataInFloat[i] = (float)sinValue;
            audioWaveTheta += sampleIncrement;
        }
    }

    return frame;
}

虽然看起来很清楚对象因为实现了Dispose方法而被清理了,但是不清楚如何处理由GetBuffer方法。 具体来说,dataInBytes和dataInFloat指针。

While it seems clear that the objects get cleaned up since they implement the Dispose method, it is not clear how to handle the memory that is allocated by the GetBuffer method.  Specifically, the dataInBytes, and dataInFloat pointers.

调用以下内容会引发异常:

Calling the following throws an exception:

System.Runtime.InteropServices.Marshal.FreeHGlobal((IntPtr)dataInBytes);

那么,我们如何释放非托管内存? 并且,在释放之后我们如何强制进行垃圾收集? 换句话说,WinRT中Free()和GC.Collect()的等价物是什么?

So, how do we free up the unmanaged memory?  And, after freeing it how do we force a garbage collection?  In other words what is the equivalent of Free() and GC.Collect() in WinRT?

Steven Edward Wood计算机工程师

Steven Edward Wood Computer Engineer

推荐答案



你不应该,在这个例子中,他们只是引用框架中的数据

You should not, in this exaple they are just references to data in frame

AudioFrame frame = new Windows.Media.AudioFrame(bufferSize);


Windows.Media .AudioFrame实现了IDisposable,你可以调用frame.Dispose()来释放内存。

Windows.Media.AudioFrame implements IDisposable and you can just call frame.Dispose() to free memory.


这篇关于[UWP] [C#]使用AudioBuffer清理非托管内存。的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆