I'm working on sensor data that is stored in .wav files. The samples represent floating point numbers between -1 and 1.
I'm reading samples from the .wav file as ByteString
s and I need a way to convert this ByteString
to a Float
. So I'm looking for a function with the following signature:
toFloat :: ByteString -> Float
For example. I'm working with a .wav file that contains 1 channel, has a framerate of 48kHz and samples consist of 24 bits. This means that each sample consists of 3 bytes and I can read it from the .wav file like this:
hGet h 3
.
Here, h
is the handle of the .wav file.
How can I convert this ByteString I get from hGet
to a Float
(between -1 and 1)?
As you can see in my previous question, I'm currently converting the ByteString
to a Double
by first converting it to an Int32
(based on Data.WAVE). Since my samples are never bigger than 32 bits, I would like to use Float
s instead of Double
s. I'm also looking for a more efficient way of doing this conversion.
EDIT
I'm currently converting the ByteString
first to an Int32
and then to a Double
. This is done by bsToDouble
:
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)
The ByteString
as input to bsToDouble
comes straight from hGet h 3
and the integer is the amount of bytes in a sample (which is 3).
Float
? You had mentionedData.Binary.IEEE754
in your previous question. In the source there is an example of decoding a 16 bit float, I would expect you need something similar for your 24 bits and then you can useData.Binary
to decode your stream. – ryachzawave
: hackage.haskell.org/package/wave. Without knowing your untimate goal it's hard to advise what is the best way to do what you want to do. – Mark KarpovConduit
s. The only part I use from the library is theByteString
toDouble
conversion. But I'm looking for something more efficient. – Thomas VanheldenFloat
. That's my problem. I do not understand the example for 16 bits enough to make my own version for 24 bits. – Thomas VanheldenByteString
, I get from reading 3 bytes from the data chunk of the .wav file, to aFloat
(between -1 and 1). E.g.hGet
gives me thisByteString
:"\131\237\242"
. It should be converted to a float containing-0.10212671756744385
– Thomas Vanhelden