2

Using the pulse-simple package I have made the following code:

main=do
    s<-simpleNew Nothing "example" Record Nothing "this is an example application"
      (SampleSpec (F32 LittleEndian) 44100 1) Nothing Nothing
    xs<-simpleRead s $ 44100*10 :: IO [Float]
    simpleFree s
    play xs

play :: [Float] -> IO ()
play d = do
    s<-simpleNew Nothing "example" Play Nothing "this is an example application"
        (SampleSpec (F32 LittleEndian) 44100 1) Nothing Nothing
    simpleWrite s d
    simpleDrain s
    simpleFree s

This works and records 10 seconds of audio and then plays it back.

I now want to encode and save the audio file (as a .wav rr whatever) so it can be played in another program or converted. I think that this is more of an audio question so for the non Haskell people I basically have an array of floats which is 44100*10 long. I suspect I'll need some other library.

Thanks in advance.

HEGX64
  • 221
  • 1
  • 9

1 Answers1

3

Seems like the Data.WAVE module from the WAVE package should do the job.

Convert your [Float] to [Int32] and that constitutes the waveSamples field of the WAVE record. Fill in the rest of the WAVEHeader and write the file using putWAVEFile.

import Data.WAVE

writeWaveFile :: String -> [Float] -> IO ()
writeWaveFile path floats = putWAVEFile path wave
  where wave = WAVE wHeader wSamples
        wHeader = WAVEHeader { waveNumChannels = 1
                             , waveFrameRate = 44100
                             , waveBitsPerSample = 32 -- or maybe 8?
                             , waveFrames = Nothing
                             }
        wSamples = [[ ... | x <- floats ]]

Fill in ... with a suitable Float -> Int32 function.

ErikR
  • 51,541
  • 9
  • 73
  • 124