在C#Xamarin.iOS

时间:2019-04-17 10:51:55

标签: c# xamarin.ios avaudioengine

我正在尝试从AVAudioPCMBuffer读取音频数据到float值的数组中。以下是我为此创建的扩展方法:

public static float[] ToFloatArray(this AVAudioPcmBuffer pcmBuffer)
{
    if ((pcmBuffer != null) && 
        (pcmBuffer.FloatChannelData != IntPtr.Zero))
    {
        int length = (Convert.ToInt32(pcmBuffer.FrameLength) * 2);
        if (length > 0)
        {
            var data = new float[length];
            Marshal.Copy(pcmBuffer.FloatChannelData, data, 0, length);
            return data;
        }
        else return new float[0];
    }
    else return null;
}

该方法似乎返回适当长度的数据(8820个样本,采样率为44100),但是,这些值似乎没有意义,其中许多值为NaN

data操作之后,下面是上述方法中Marshal.Copy上的 QuickWatch

QuickWatch on data output from AVAudioPcmBuffer

我原本打算使用float[]值创建一个VU表,但是当进行实时监视时,这些值似乎不会随麦克风输入而发生显着变化,我也不明白为什么许多值包含不是数字NaN)。

我确实知道AVAudioPcmBuffer包含有效的音频数据,因为我正在通过SFSpeechAudioBufferRecognitionRequest发送到Append(AVAudioPcmBuffer audioPcmBuffer),并且语音识别功能正常。

我怀疑Marshal.Copy可能正在复制错误的数据。 有人可以确认这一点,和/或提出在C#Xamarin for iOS中从float[]访问AVAudioPcmBuffer值的正确方法吗?

2 个答案:

答案 0 :(得分:0)

FloatChannelData返回的指针为浮点指针,而不是单个指针。因此,您需要取消引用float **才能进入float *。因此,假设在您的示例中您正在处理单声道,则只需更改:

Marshal.Copy(pcmBuffer.FloatChannelData, data, 0, length)

Marshal.Copy(pcmBuffer.FloatChannelData[0], data, 0, length)

答案 1 :(得分:0)

FloatChannelData是指向通道的指针,因此要获取字节,您需要执行此操作-

var channels = (IntPtr*)buffer.FloatChannelData.ToPointer();
Marshal.Copy(channels[0], data, 0, length);