Hi,

An earlier version of this question is cross-posted at StackOverflow.

What should I use for precise (and eventually, concurrency-compatible) timing in Haskell? I want to make rhythms. I tried the following to produce a repeating rhythm in which one note is twice as long as the other two. (That rhythm is encoded by the list [1,1,2].)

    import Control.Concurrent
    import Text.Printf
    import Control.Monad
    
    main = mapM_ note (cycle [1,1,2])
    
    beat = round (10^6 / 4) -- measured in microseconds
    
    note :: Int -> IO ()
    note n = do
        threadDelay $ beat * n
        printf "\BEL\n"

When I run it the long note is three times as long as the others, not twice. If I speed it up, by changing the number 4 to a 10, the rhythm is destroyed completely: the notes all have the same length.

threadDelay is guaranteed to wait at least as long, but potentially longer than, what the caller specifies. Another potential problem could be buffering in printf. (Eventually I intend to replace the printf statement with OSC output to a sound generator.)

Thanks,
Jeff