Double转换的ByteString表示 [英] ByteString representation of a Double conversion
问题描述
我正在编写自己的 WAVE
解析器,它使用 Conduit ,这样我就可以通过管道一个接一个地传送值。
我通过 hGet
从.wav文件中获取样本(n是每个样本的字节数wav文件):
字节< - hGet hn
这给了我一个ByteString,其中包含样本Double值的表示。例如:
\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
,convert [Word8]
to Word32
,然后使用 Float -ieee754-0.4.4 / docs / Data-Binary-IEEE754.htmlrel =nofollow noreferrer> Data.Binary.IEEE754 。这会是一个很好的解决方案吗?一个问题是我目前不知道如何将[Word8]的四元素列表转换为Word32。
这是我当前的解决方案,将ByteString转换为双精度:
convertNBytesLen :: [Word8] - > Int32
convertNBytesLen = foldr accum 0
其中accum bs a = 256 * a + fromInteral bs
bsToDouble :: S.ByteString - > Int - > Double
bsToDouble bs n = if intV> = 0
then fromIntegral intV / 2147483647
else - (fromIntegral intV /(-2147483648))
其中intV = convertNBytesLen(S)解包bs)`shift`(32 - 8 * n)
我想知道这是否可以以更有效的方式完成。
I'm writing my own WAVE
parser that uses Conduit so I can stream values, one by one, through a pipeline.
I get a sample from a .wav file via hGet
(n is the number of bytes per sample for that wav file):
bytes <- hGet h n
This gives me a ByteString with a representation of the Double value of the sample. E.g.:
"\131\237\242"
represents -0.10212671756744385
"g\238\242"
represents -0.10209953784942627
"\215\238\242"
represents -0.10208618640899658
.
The possible values are between -1 and +1.
Is there any convenient way to do this conversion? Is there a library available to do this?
I've taken a look at existing WAVE
parsers for Haskell. Data.WAVE parses a .wav
file and returns the samples as left-justified Int32
values. I've found a workaround where I use it's library functions to convert my ByteString
to a left-justified Int32
and then convert it to a Double
using the library's sampleToDouble
function. This works, but I'm wondering if there is a more direct way of solving this problem.
Another possible solution would be to convert the ByteString
to [Word8]
with ByteString.unpack
, convert [Word8]
to Word32
and then convert this value to a Float
using the conversion functions from Data.Binary.IEEE754. Would this be a good solution? One problem is that I currently don't know how to convert a four-element list of [Word8] to Word32.
This is my current solution to turn the ByteString into a double:
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)
I'm wondering if this can be done in a more efficient manner.
这篇关于Double转换的ByteString表示的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!