ByteString表示双重转换
问题描述:
我正在编写我自己的WAVE
解析器,它使用Conduit,所以我可以通过管道一个接一个地传输值。ByteString表示双重转换
我通过hGet
得到.wav文件的样本(n为样本的字节为wav文件数):
bytes <- hGet h n
这给了我与双的表示一个字节串样品的价值。例如: -
"\131\237\242"
代表-0.10212671756744385
"g\238\242"
代表-0.10209953784942627
"\215\238\242"
代表-0.10208618640899658
。
可能的值介于-1和+1之间。
有没有方便的方法来做这种转换?有没有图书馆可以做到这一点?
我查看了现有的用于Haskell的WAVE
解析器。 Data.WAVE解析.wav
文件并将样本作为左对齐Int32
值返回。我找到了解决方法,我使用它的库函数将ByteString
转换为左对齐的Int32
,然后使用库的sampleToDouble
函数将其转换为Double
。这有效,但我想知道是否有更直接的方法来解决这个问题。
另一种可能的解决办法是将ByteString
转换为[Word8]
与ByteString.unpack
,转换到[Word8]
和Word32
然后该值使用转换函数从Data.Binary.IEEE754转换为Float
。这会是一个很好的解决方案吗?一个问题是我目前不知道如何将[Word8]的四元素列表转换为Word32。
答
这是我目前的解决方案打开字节字符串到双:
convertNBytesLen :: [Word8] -> Int32
convertNBytesLen = foldr accum 0
where accum bs a = 256 * a + fromIntegral bs
bsToDouble :: S.ByteString -> Int -> Double
bsToDouble bs n = if intV >= 0
then fromIntegral intV/2147483647
else - (fromIntegral intV/(-2147483648))
where intV = convertNBytesLen (S.unpack bs) `shift` (32 - 8 * n)
我不知道这是否可以以更有效的方式来完成。
你看过'bytestring-lexing'库中的'readDouble'吗? – liminalisht
那些看起来不像我的十六进制字符。 –
@liminalisht我有。但我似乎无法安装该软件包。它看起来像bitrotten ... –