带有 rsound 的球拍延迟
Racket latency with rsound
我用 Racket 编写了这个程序,它从一组 15 个音符中生成 32 个随机音符,然后播放它们。每个音符的持续时间应为 0.25 秒。当我 运行 时,它会产生延迟,使旋律听起来不合拍。
怎么才能运行正常呢?
这是程序:
#lang racket
(provide (all-defined-out))
(require rsound)
(require rsound/piano-tones)
(define-syntax-rule (note y x)
(begin
(play (piano-tone y))
(sleep x)
(stop)))
(define (random-element list)
(list-ref list (random (length list))))
(define-syntax-rule (random-note)
(note (random-element '(40 42 43 45 47 48 50 52 54 55 57 59 60 62 64)) 0.25))
(for ([i 32])
(random-note))
首先,来自piano-tone
are not really meant to be truncated like that, although you can do it with the clip
的笔记起作用了。
其次,你这里的问题是你依赖于你的计算机执行代码的速度,这在本质上是不一致的。
更好的方法是使用 make-pstream
。并稍后将笔记排队到 运行。这样在播放音符时就不会出现基于处理器的间隙。
(另外,作为旁注,当您像这样使用循环时,in-range
可用于加速循环。)
把它们放在一起(使用 clip 剪掉你的笔记),你的程序看起来像这样(为了简洁我使用了幻数,显然你会想 运行 通过实际计算得到0.25 秒):
#lang racket
(require rsound
rsound/piano-tones)
(define stream (make-pstream))
(define count 10000)
(define (note y x)
(pstream-queue stream (clip (piano-tone y) 0 10000) count)
(set! count (+ count x)))
(define (random-element list)
(list-ref list (random (length list))))
(define (random-note)
(note (random-element '(40 42 43 45 47 48 50 52 54 55 57 59 60 62 64)) 10000))
(for ([i (in-range 32)])
(random-note))
最后,如果您想将所有这些打包成一个可执行文件,程序将在队列完成之前终止。因此,在等待队列完成的程序末尾创建一个忙循环(通过使用 pstream-queue-callback
)。
将此添加到程序末尾:
(define ok-to-exit? #f)
(pstream-queue-callback stream (lambda () (set! ok-to-exit? #t)) count)
(let loop ()
(sleep 0.1)
(unless ok-to-exit?
(loop)))
我用 Racket 编写了这个程序,它从一组 15 个音符中生成 32 个随机音符,然后播放它们。每个音符的持续时间应为 0.25 秒。当我 运行 时,它会产生延迟,使旋律听起来不合拍。
怎么才能运行正常呢?
这是程序:
#lang racket
(provide (all-defined-out))
(require rsound)
(require rsound/piano-tones)
(define-syntax-rule (note y x)
(begin
(play (piano-tone y))
(sleep x)
(stop)))
(define (random-element list)
(list-ref list (random (length list))))
(define-syntax-rule (random-note)
(note (random-element '(40 42 43 45 47 48 50 52 54 55 57 59 60 62 64)) 0.25))
(for ([i 32])
(random-note))
首先,来自piano-tone
are not really meant to be truncated like that, although you can do it with the clip
的笔记起作用了。
其次,你这里的问题是你依赖于你的计算机执行代码的速度,这在本质上是不一致的。
更好的方法是使用 make-pstream
。并稍后将笔记排队到 运行。这样在播放音符时就不会出现基于处理器的间隙。
(另外,作为旁注,当您像这样使用循环时,in-range
可用于加速循环。)
把它们放在一起(使用 clip 剪掉你的笔记),你的程序看起来像这样(为了简洁我使用了幻数,显然你会想 运行 通过实际计算得到0.25 秒):
#lang racket
(require rsound
rsound/piano-tones)
(define stream (make-pstream))
(define count 10000)
(define (note y x)
(pstream-queue stream (clip (piano-tone y) 0 10000) count)
(set! count (+ count x)))
(define (random-element list)
(list-ref list (random (length list))))
(define (random-note)
(note (random-element '(40 42 43 45 47 48 50 52 54 55 57 59 60 62 64)) 10000))
(for ([i (in-range 32)])
(random-note))
最后,如果您想将所有这些打包成一个可执行文件,程序将在队列完成之前终止。因此,在等待队列完成的程序末尾创建一个忙循环(通过使用 pstream-queue-callback
)。
将此添加到程序末尾:
(define ok-to-exit? #f)
(pstream-queue-callback stream (lambda () (set! ok-to-exit? #t)) count)
(let loop ()
(sleep 0.1)
(unless ok-to-exit?
(loop)))