From: Brian Candler Date: 2007-05-08T16:57:05+09:00 Subject: Re: ulaw audio over network On Tue, May 08, 2007 at 04:28:37PM +0900, eden li wrote: > It looks like this is a pure #sleep issue and has nothing to do with > sending data over a socket. If you setup a simple loop and average > the time sleep actually sleeps, you get the following: > > want = 0.008, actual (averaged over 1000 attempts) = > 0.00800016689300537 > want = 0.01, actual (averaged over 1000 attempts) = 0.0122149839401245 > want = 0.012, want (averaged over 1000 attempts) = 0.0120026016235352 > > Not exactly sure what's so special about 10ms... > > Here's what I ran to produce the output above: > > def try(n) > dt, dc = [0, 0] > 1_000.times do > t = Time.now.to_f > sleep n > dt += Time.now.to_f - t > dc += 1 > end > dt / dc > end > > [0.008, 0.01, 0.012].each do |n| > puts "want = #{n}, actual (averaged over 1000 attempts) = #{try(n)}" > end Regardless of how well Ruby's sleep worked, this would still be inaccurate because of the time needed to execute the other things in the loop. Try something like this instead: def run t = Time.now.to_f 1_000.times do yield if block_given? t += 0.01 interval = t - Time.now.to_f sleep(interval) if interval > 0 # sleep barfs with negative values end end t1 = Time.now run { x = x } t2 = Time.now puts t2 - t1 Your UDP packets will have a small amount of jitter, which the far end's jitterbuffer will handle (and if this is going over the Internet, you'll get a lot more jitter from other sources), but will be sent at an average rate of one every 10ms. Brian.