Double转换的ByteString表示 [英] ByteString representation of a Double conversion

查看:196
本文介绍了Double转换的ByteString表示的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在编写自己的 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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆