将内存流转换为双数组?

Posted

技术标签:

【中文标题】将内存流转换为双数组?【英文标题】:Convert memorystream to double-array? 【发布时间】:2013-01-28 15:15:48 【问题描述】:

我从波形文件中获得了原始音乐数据的 pcm 流,并希望将其转换为双数组(之后应用 fft)。

我现在得到的结果包含非常高或低的双数(1.0E-200 和 1.0E+300),我不确定这些是否正确。

这是我现在使用的代码:

WaveStream pcm = WaveFormatConversionStream.CreatePcmStream(mp3);
double[] real = new double[pcm.Length];
byte[] buffer = new byte[8];
int count = 0;

while ((read = pcm.Read(buffer, 0, buffer.Length)) > 0)

   real[count] = BitConverter.ToDouble(buffer, 0);
   count++;

【问题讨论】:

我不知道音频流,但也许你真的想将音频数据的每个字节转换成双精度,或者它可能是 big-endian 与 little-endian 的问题?如果是这样,您需要在转换为双精度之前反转每组 8 个字节。 【参考方案1】:

您的 PCM 流几乎可以肯定是 16 位的。所以不要使用BitConverter.ToDouble,而是使用ToInt16。然后除以 32768.0 进入范围 +/- 1.0

【讨论】:

【参考方案2】:

我意识到这个问题已经过时了;但是,我想我可能会提供这种替代方法来调用 BitConverter.ToDouble。

    public static double[] ToDoubleArray(this byte[] bytes)
    
        Debug.Assert(bytes.Length % sizeof(double) == 0, "byte array must be aligned on the size of a double.");

        double[] doubles = new double[bytes.Length / sizeof(double)];
        GCHandle pinnedDoubles = GCHandle.Alloc(doubles, GCHandleType.Pinned);
        Marshal.Copy(bytes, 0, pinnedDoubles.AddrOfPinnedObject(), bytes.Length);
        pinnedDoubles.Free();
        return doubles;
    

    public static double[] ToDoubleArray(this MemoryStream stream)
    
        return stream.ToArray().ToDoubleArray();
    

【讨论】:

以上是关于将内存流转换为双数组?的主要内容,如果未能解决你的问题,请参考以下文章

将内存流拆分为 bytearray

C#字符串字节数组和内存流间的相互转换 - IT浪潮之巅

如何将 NAudio WaveStream 写入内存流?

如何使用内存流、NAudio 和 LameMP3 将音频 aiff 转换为 MP3

内存流中的 InvalidOperationException

Java核心类库-IO-字节数组流/内存流