Прежде всего, ноты, которые приходят из piano-tone
не на самом деле означает быть усечены, как, что, хотя вы можете сделать это с помощью функции clip
.
Во-вторых, ваша проблема заключается в том, что вы полагаетесь на то, как быстро ваш компьютер будет выполнять код, который по своей сути непоследователен.
Гораздо лучший подход - использовать make-pstream
. И поставить в очередь записки, чтобы запустить их позже. Таким образом, при воспроизведении нот не будет пробелов, основанных на вашем процессоре.
(Также, как примечание стороны in-range
может быть использован для ускорения для петель, когда вы их используете, как это.)
Положите все это вместе (используя зажим, чтобы сократить ваши заметки в выключенном состоянии), ваша программа будет искать что-то вроде этого (я использовал магические числа для краткости, очевидно, вы хотели бы, чтобы пробежать фактические расчеты, чтобы получить 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)))
Спасибо! Но теперь у меня другая проблема. Я преобразовал его в исполняемый файл, и он завершает работу до того, как будет запущен цикл for. Что я могу сделать для всех заметок, которые будут воспроизводиться? –
Что происходит, скорее всего, что make-pstream происходит в другом потоке, и основной поток не ждет его завершения до его выхода. Вероятно, самый простой способ исправить это - добавить «pstream-queue-callback» в конце вашей песни, которая сигнализирует о завершении программы. Я отвечу на этот вопрос. –
(Кроме того, вы могли бы просто «поспать», но это может закончиться до того, как ваша программа закончит игру. –