Skip to content
This repository was archived by the owner on Jun 13, 2025. It is now read-only.
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion BootTidal.hs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import Sound.Tidal.Context
import System.IO (hSetEncoding, stdout, utf8)
hSetEncoding stdout utf8

tidal <- startTidal (superdirtTarget {oLatency = 0.1, oAddress = "127.0.0.1", oPort = 57120}) (defaultConfig {cVerbose = True, cFrameTimespan = 1/20})
tidal <- startTidal (superdirtTarget {oLatency = 0.05, oAddress = "127.0.0.1", oPort = 57120}) (defaultConfig {cVerbose = True, cFrameTimespan = 1/20})
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm late at the party, but why this latency has been lowered? In my setup I have to raise it to 0.2 since it really depend on everyone's setup, and especially for old-computers this value could cause a lot of late messages.

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just to be sure, is your comment based on before or after the change to use Ableton Link for scheduling?

To avoid late messages, cProcessAhead can be adjusted. It's current value 3/10 instructs Tidal to schedule events when they are 300ms away on the Link timeline.

oLatency adjusts how much time SuperDirt needs for sound synthesis. A higher value will start the synthesis earlier. A higher oLatency requires a higher value for cProcessAhead if we want to avoid late messages.

It would be great to have a report from different people to learn what settings they use. That input could help us set better defaults. Since scheduling has changed significantly, I did not trust the old values and thus changed them to fit my setup. My thinking was that it's better to have values that have been tested with the new scheduling than to stick to the old values.

Copy link
Copy Markdown
Contributor

@ndr-brt ndr-brt Jul 15, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Before, didn't have the chance to try the new scheduler...
I always thought (and it always behave in the way...) that the oLatency value is added to the timestamp that's sent to superdirt to trigger the sounds, and when I set it under 0.2 late messages start to appear.

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You are correct about the old behaviour @ndr-brt! I hope to make a technical writeup about the new behaviour in early fall as part of the documentation that needs to be added. cProcessAhead achieves the same effect but in a different way, while oLatency is now only useful for alignment on the Link timeline.


:{
let only = (hush >>)
Expand Down
2 changes: 1 addition & 1 deletion src/Sound/Tidal/Config.hs
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ defaultConfig = Config {cCtrlListen = True,
cCtrlBroadcast = False,
cFrameTimespan = 1/20,
cEnableLink = True,
cProcessAhead = 1/4,
cProcessAhead = 3/10,
cTempoAddr = "127.0.0.1",
cTempoPort = 9160,
cTempoClientPort = 0, -- choose at random
Expand Down
7 changes: 4 additions & 3 deletions src/Sound/Tidal/Stream.hs
Original file line number Diff line number Diff line change
Expand Up @@ -551,19 +551,20 @@ setPreviousPatternOrSilence stream =
-- Send events live by delaying the thread
send :: Maybe O.UDP -> Cx -> Double -> Double -> (Double, Bool, O.Message) -> IO ()
send listen cx latency extraLatency (time, isBusMsg, m)
| oSchedule target == Pre BundleStamp = sendBndl isBusMsg listen cx $ O.Bundle (time + extraLatency) [m]
| oSchedule target == Pre BundleStamp = sendBndl isBusMsg listen cx $ O.Bundle timeWithLatency [m]
| oSchedule target == Pre MessageStamp = sendO isBusMsg listen cx $ addtime m
| otherwise = do _ <- forkOS $ do now <- O.time
threadDelay $ floor $ (time - now - latency + extraLatency) * 1000000
threadDelay $ floor $ (timeWithLatency - now) * 1000000
sendO isBusMsg listen cx m
return ()
where addtime (O.Message mpath params) = O.Message mpath ((O.int32 sec):((O.int32 usec):params))
ut = O.ntpr_to_ut (time + extraLatency)
ut = O.ntpr_to_ut timeWithLatency
sec :: Int
sec = floor ut
usec :: Int
usec = floor $ 1000000 * (ut - (fromIntegral sec))
target = cxTarget cx
timeWithLatency = time - latency + extraLatency

-- Interaction

Expand Down