Привет. Объясняю идиотское название треда: я решил замутить штуку для синтеза звука в реальном времени, но не продумал одну вещь и жестко напоролся. Итак, штука состоит из менеджера, управляющего миксером и бекэндом, в который звук выводится. Миксер может собирать данные от подключенных к нему генераторов и подготавливать данные для записи в бэкенд. Данные генерируются и записываются буфером.
Сейчас менеджер работает в своём потоке, выполняя цикл, генерирующий данные и сразу записывающий их:
(defmethod run ((manager simple-manager))
(let ((backend (manager-backend manager)))
(backend-init backend)
(flet ((run-loop ()
(let* ((settings (audio-settings (manager-backend manager)))
(channels (audio-settings-channels settings))
(size (* *buffer-size* channels))
(buffer (make-array (list size) :element-type '(signed-byte 24))))
(loop while (simple-manager-runningp manager) do
(write-buffer backend
(prepare-buffer (manager-mixer manager)
buffer))))))
(setf (simple-manager-runningp manager) t
(simple-manager-thread manager) (make-thread #'run-loop :name "Gen-write loop"))))
manager)
Есть ещё вариант, не создающих поток; и, наверное, будет вариант с очередью для хранения буферов про запас.
Сделано изменяемым всё, кроме параметров бекенда (бит на семпл, sample rate, number of channels).
Так вот я не продумал главное, если изменю параметр генератора (пока есть всего один, генерурующий синусоиду), как мне сделать так, чтобы изменения сразу вступили в силу? Ведь надо ждать, пока буфер запишется, а потом сгенерируется новый. В общем я ССЗБ. Есть идея, что может есть инструмент, которым можно прервать write-sequence (она вызвается из write-buffer), перенаполнить буфер и пойти дальше. Да и желательно, чтоб звук не дергался :)
В общем, ваши идеи, господа, как сделать механизм real-time генерации/записи наиболее Ъ.