GHC's timing: Now solid enough for music?

I just discovered Tom Murphy's Vivid-Synth[1], a Haskell library that lets you control SuperCollider. (A few very slight changes allowed me to get it to work in Stack instead of Cabal, as described here[2,3].) TidalCycles[4] also controls SuperCollider from Haskell. It does tortuous backflips to hand the timing job over to SuperCollider. If I recall correctly, that was because SC's timing was more solid than Haskell's. I modified the Vivid demo to go faster and have a few more voices[5], and tried running it at the same time as Spotify and Youtube and apt upgrade and loading LibreOffice and playing some music in VLC, and I detected (by ear) no timing errors. Can I expect GHC's maybe-new rhythmic stability to hold up? [1] http://www.vivid-synth.com/ [2] https://github.com/vivid-synth/vivid/issues/5 [3] https://github.com/JeffreyBenjaminBrown/vivid/commit/3d25266d4495d9dd8e573f3... [4] https://tidalcycles.org/ [5] https://github.com/JeffreyBenjaminBrown/vivid/blob/jbb/jbb/sine.hs -- Jeff Brown | Jeffrey Benjamin Brown Website https://msu.edu/~brown202/ | Facebook https://www.facebook.com/mejeff.younotjeff | LinkedIn https://www.linkedin.com/in/jeffreybenjaminbrown(spammy, so I often miss messages here) | Github https://github.com/jeffreybenjaminbrown

Vivid has combinators to schedule music with sample-accurate timing (it's as simple as prepending e.g. "doScheduledIn 0.2" to any VividAction, where 0.2 is 0.2 seconds from now - everything will be precise relative to that start time). "doScheduledAt" is another useful one. You can also write to a file with precise timing by prepending e.g. 'writeNRT "foo.wav"'. Still, I'd be curious to know the more-general answer to the question of how accurate we can expect forkIO and threadDelay to be, under normal load. E.g. how often/by how much does threadDelay take longer than needed to wake? To my ears and a few quick tests it's usually surprisingly good. Tom
El 2 jul 2018, a las 19:26, Jeffrey Brown
escribió: I just discovered Tom Murphy's Vivid-Synth[1], a Haskell library that lets you control SuperCollider. (A few very slight changes allowed me to get it to work in Stack instead of Cabal, as described here[2,3].)
TidalCycles[4] also controls SuperCollider from Haskell. It does tortuous backflips to hand the timing job over to SuperCollider. If I recall correctly, that was because SC's timing was more solid than Haskell's.
I modified the Vivid demo to go faster and have a few more voices[5], and tried running it at the same time as Spotify and Youtube and apt upgrade and loading LibreOffice and playing some music in VLC, and I detected (by ear) no timing errors.
Can I expect GHC's maybe-new rhythmic stability to hold up?
[1] http://www.vivid-synth.com/ [2] https://github.com/vivid-synth/vivid/issues/5 [3] https://github.com/JeffreyBenjaminBrown/vivid/commit/3d25266d4495d9dd8e573f3... [4] https://tidalcycles.org/ [5] https://github.com/JeffreyBenjaminBrown/vivid/blob/jbb/jbb/sine.hs
-- Jeff Brown | Jeffrey Benjamin Brown Website | Facebook | LinkedIn(spammy, so I often miss messages here) | Github

On 3 Jul 2018, at 10:45 am, amindfv@gmail.com wrote:
Vivid has combinators to schedule music with sample-accurate timing (it's as simple as prepending e.g. "doScheduledIn 0.2" to any VividAction, where 0.2 is 0.2 seconds from now - everything will be precise relative to that start time). "doScheduledAt" is another useful one. You can also write to a file with precise timing by prepending e.g. 'writeNRT "foo.wav”'.
Still, I'd be curious to know the more-general answer to the question of how accurate we can expect forkIO and threadDelay to be, under normal load. E.g. how often/by how much does threadDelay take longer than needed to wake? To my ears and a few quick tests it's usually surprisingly good.
The question here is somewhat unrelated to the statement above. Audio streams are buffered and are consumed (and thus played back) by the audio hardware which has its own clock. Ensuring that samples are played at the correct time with respect to each other is trivial as you just need to write them into the audio buffer at the correct time. Even if there is a 10ms delay between a user pressing a key and the sample playing, most humans will perceive those actions as simultaneous. For the second question about forkIO and threadDelay, the I was working on the Repa data parallel library a few years ago (~2013) I did some testing and the time to wake up a GHC green thread on a separate OS process was in the order of 200 microseconds. Note that this is to wake up a OS process on a separate core. The time to communicate to another process via a MVar should be much shorter. The time to wake up a process is also affected by whether you’ve set the core affinity — so that a particular GHC execution capability is bound to a particular OS process / hardware core. See S5.1.1 of the following paper (on page 8) http://benl.ouroborus.net/papers/2012-guiding/guiding-Haskell2012.pdf http://benl.ouroborus.net/papers/2012-guiding/guiding-Haskell2012.pdf This includes thread scope diagrams showing the delay between forking a computation and it actually starting. Ben.
participants (3)
-
amindfv@gmail.com
-
Ben Lippmeier
-
Jeffrey Brown