Уже замечено, что во многих эмуляторах, которые сделаны в учебных или демонстрационных целях, отсутствует эмуляция звука. Думаю, что это не с простаВедь необходимо в реальном времени равномерно формировать нужные данные и непрерывно подкидывать их в звуковой буфер. Не очень простая задача.
Свой первый звук я выводил в эмуляторе ZX-Pilot для PalmOS. Там я особо не заморачивался и напрямую на ассемблере перенаправлял команды OUT Z80 в соответствующий порт Paml-устройства. При таком подходе, низкоуровневом программировании и полном отсутствии каких-либо задержек в ядре эмулятора результат превзошёл мои ожидания.
Второй раз я сделал звук в эмуляторе "Ну, погоди" на Python. Там я использовал подход синхронизации по звуку по подсказке IgorR76. То есть процессор работает заполняя звуковой буфер, а потом, как он заполнится выводятся звук и сформированная картинка. Но там был просто канонический случай. Частота эмулируемого процессора 16384 Гц, 1 команда = 1 такт. Поэтому я просто выставил частоту дискретизации звука 16384 Гц и последовательно после выполнения каждой команды заполнял буфер единицами и нулями, в зависимости от состояния порта. Всё идеально.
И вот я, наконец, созрел прикрутить звук вот сюда по тому же методу. И тут у меня наступил затык. В силу того, что частота процессора существенно отличается от частоты сэмплирования, да ещё и команды процессора имеют разное время исполнения, потребуются некоторые преобразования.
Например, частота КР580ВМ80А - 2 МГц, а частота сэмплирования 44100 Гц (ну или 22 100 Гц - не так важно). Получается, что на 1 Гц звука приходится 2 000 000 / 44 100 = 45,35 такта процессора. Во-первых, если синхронизироваться по звуку, то придётся менять частоту виртуального процессора - 45 * 44 100 = 1 984 500 Гц. Думаю, что это пережить можно. Но не совсем понятно как правильно 45 единиц и нулей преобразовать в одно число 0-255? Ведь за 45 тактов значение порта может несколько раз поменяться и тут не будет чистых нулей и единиц.
В голову приходит и другой вариант: писать в буфер все данные с частотой 2 МГц за какой-то короткий промежуток времени, а потом этот буфер перед проигрыванием какой-нибудь готовой процедурой (ну или своей) преобразовывать в те же 44 100 Гц. Но тут я боюсь, просто буду не успевать производить такие манипуляции, а тем более на Python.
Пока я веду речь о простом однобитном звуке.
В общем, подскажите, как делать правильно, быстро и чтобы качество звука было на высоте?
P.S. Пока всё делаю на Python, чтобы разобраться с вопросом. А конечная цель: сделать то же самое на ARM-ассемблере. Но это в отдалённом будущем.




Ведь необходимо в реальном времени равномерно формировать нужные данные и непрерывно подкидывать их в звуковой буфер. Не очень простая задача.
Ответить с цитированием
Размещение рекламы на форуме способствует его дальнейшему развитию 
