我正在尝试从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 :
我原本打算使用float[]
值创建一个VU表,但是当进行实时监视时,这些值似乎不会随麦克风输入而发生显着变化,我也不明白为什么许多值包含不是数字(NaN
)。
我确实知道AVAudioPcmBuffer
包含有效的音频数据,因为我正在通过SFSpeechAudioBufferRecognitionRequest
发送到Append(AVAudioPcmBuffer audioPcmBuffer)
,并且语音识别功能正常。
我怀疑Marshal.Copy
可能正在复制错误的数据。 有人可以确认这一点,和/或提出在C#Xamarin for iOS中从float[]
访问AVAudioPcmBuffer
值的正确方法吗?
答案 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);