2016-12-14 13 views
1

Conduitを使用する独自のWAVEパーサーを作成していますので、パイプラインを通じて1つずつ値をストリームできます。Double変換のByteString表現

私はhGetを経由して.wavファイルからサンプルを得る(nはwavファイルのサンプルあたりのバイト数です):

bytes <- hGet h n

これは私に二重の表現で延ByteStringを与えますサンプルの値。例えば:

"\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.unpack[Word8]ByteString変換Word32[Word8]を変換しData.Binary.IEEE754から変換関数を使用してFloatこの値を変換することであろう。これは良い解決策でしょうか? 1つの問題は、現在、[Word8]の4要素リストをWord32に変換する方法がわからないことです。

+0

あなたは 'bytestring-lexing'ライブラリの' readDouble'を見ましたか? – liminalisht

+1

それらは私に16進文字のように見えません。 –

+0

@liminalisht私は持っています。しかし、私はパッケージをインストールするように見えることはできません。それはビットロトになっているようです... –

答えて

0

これは、二重に延ByteStringをオンに私の現在のソリューションです。これは、より効率的な方法で行うことができる場合、私は思ったんだけど

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) 

関連する問題