Важная информация

User Tag List

Страница 1 из 2 12 ПоследняяПоследняя
Показано с 1 по 10 из 14

Тема: Общий подход к эмуляции биперного звука

  1. #1
    Administrator Аватар для CityAceE
    Регистрация
    13.01.2005
    Адрес
    г. Москва
    Сообщений
    4,574
    Записей в дневнике
    7
    Спасибо Благодарностей отдано 
    399
    Спасибо Благодарностей получено 
    1,207
    Поблагодарили
    394 сообщений
    Mentioned
    48 Post(s)
    Tagged
    0 Thread(s)

    По умолчанию Общий подход к эмуляции биперного звука

    Уже замечено, что во многих эмуляторах, которые сделаны в учебных или демонстрационных целях, отсутствует эмуляция звука. Думаю, что это не с проста Ведь необходимо в реальном времени равномерно формировать нужные данные и непрерывно подкидывать их в звуковой буфер. Не очень простая задача.

    Свой первый звук я выводил в эмуляторе 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-ассемблере. Но это в отдалённом будущем.
    С уважением, Станислав.

  2. #1
    С любовью к вам, Yandex.Direct
    Размещение рекламы на форуме способствует его дальнейшему развитию

  3. #2
    Guru Аватар для svofski
    Регистрация
    20.06.2007
    Адрес
    С.-Петербург
    Сообщений
    4,116
    Спасибо Благодарностей отдано 
    793
    Спасибо Благодарностей получено 
    658
    Поблагодарили
    403 сообщений
    Mentioned
    22 Post(s)
    Tagged
    0 Thread(s)

    По умолчанию

    В v06x звук тактирует видео.
    Все семплы с таймера не пишутся в буфер, это был бы очень большой буфер, а пропускаются через ресемплер, который превращает их в 48000 отсчетов в секунду и ресемплированный сигнал уже набивает буфер.

    Цифры такие: частота ви53 1.5мгц. Коэффициент пересчета для ресемплера ×5 ÷156, получается ~48077, годится.

    Ресемплер самая интересная вещь. Мне в его написании очень помогли ivagor и бумага "Introduction to Digital Resampling" by Dr. Mike Porteous (гуглится).

    Я думаю, что для начала можно взять scipy.signal.resample.
    Последний раз редактировалось svofski; 19.04.2020 в 10:55.
    Больше игр нет

  4. Эти 2 пользователя(ей) поблагодарили svofski за это полезное сообщение:

    CityAceE (19.04.2020), hobot (21.04.2020)

  5. #3
    Guru
    Регистрация
    24.01.2008
    Адрес
    Уфа
    Сообщений
    3,847
    Спасибо Благодарностей отдано 
    84
    Спасибо Благодарностей получено 
    229
    Поблагодарили
    167 сообщений
    Mentioned
    9 Post(s)
    Tagged
    0 Thread(s)

    По умолчанию

    Цитата Сообщение от CityAceE Посмотреть сообщение
    Но не совсем понятно как правильно 45 единиц и нулей преобразовать в одно число 0-255?
    кол-во едениц * 255 / 45
    Или тут какие-то подводные камни есть?

  6. Этот пользователь поблагодарил b2m за это полезное сообщение:

    CityAceE (19.04.2020)

  7. #4
    Administrator Аватар для CityAceE
    Регистрация
    13.01.2005
    Адрес
    г. Москва
    Сообщений
    4,574
    Записей в дневнике
    7
    Спасибо Благодарностей отдано 
    399
    Спасибо Благодарностей получено 
    1,207
    Поблагодарили
    394 сообщений
    Mentioned
    48 Post(s)
    Tagged
    0 Thread(s)

    По умолчанию

    Цитата Сообщение от svofski Посмотреть сообщение
    Все семплы с таймера не пишутся в буфер, это был бы очень большой буфер, а пропускаются через ресемплер
    Собственно, как я и предположил во втором варианте. Видимо, придётся попробовать так, но боюсь, что на тормозном Python не удастся добиться приемлемого результата.

    Цитата Сообщение от svofski Посмотреть сообщение
    Мне в его написании очень помогли ivagor
    Иван прям везде успевает Я когда упёрся в этот вопрос, тоже первый, о ком я подумал был как раз Иван

    Цитата Сообщение от b2m Посмотреть сообщение
    кол-во единиц * 255 / 45
    Или тут какие-то подводные камни есть?
    Опять же, такой вариант первым пришёл мне в голову. Но я не уверен, что это будет работать так, как должно. Вот я и хотел узнать, есть ли какие-то подводные камни?

    Я сейчас проиллюстрирую примером с идеальными условиями из "Ну, погоди!":

    Вот с такими значениями инициализируется звуковой буфер:
    Код:
    # Инициализация звукового буфера, должна быть раньше всех инициализаций!
    # pygame.mixer.init(frequency=16384, size=8, channels=1, buffer=1024)
    pygame.mixer.init(16384, 8, 1, 1024)
    А вот так буфер заполняется:
    Код:
    sound = cpu.exec_op_code()
    buffer[i] = sound * 255
    То есть после исполнения каждой команды процессора снимается значение порта, отвечающего за звук. Если там 0, то в буфер пишется 0, а если единица, то 255. И потом, по достижении конца буфера (1 кб), выводится 8-битный одноканальный звук с частотой дискретизации 16 кГц.

    Будет ли корректным результат, если я сложу 45 значений порта (единицы и нули), умножу их на 255 и разделю на 45, откинув дробную часть? Видимо, пока не проведу эксперимент, не узнаю. Однако для этого придётся поменять логику ядра эмулятора. Сейчас в эмуляторе виртуальный процессор тактируется экраном: экран рисуется 50 раз в секунду, а между выводами экрана отрабатывается 2 000 000 Гц / 50 = 40 000 тактов и ждёт отрисовки следующего экрана.
    С уважением, Станислав.

  8. #5
    Guru Аватар для svofski
    Регистрация
    20.06.2007
    Адрес
    С.-Петербург
    Сообщений
    4,116
    Спасибо Благодарностей отдано 
    793
    Спасибо Благодарностей получено 
    658
    Поблагодарили
    403 сообщений
    Mentioned
    22 Post(s)
    Tagged
    0 Thread(s)

    По умолчанию

    Собрать здоровенный буфер и скормить его на обработку scipy будет относительно быстро, а качество ресемплера в scipy.signal.resample_poly на высоте. Делать ЦОС прямо на Питоне семпл за семплом будет медленно. С другой стороны, если это прототип, то его рилтаймовые характеристики неважны. Пока отлаживаешь алгоритм пусть он работает хоть 10 минут за 1 секунду реального времени. Оптимизировать надо когда отлажен принцип работы.

    Все сложить и поделить -- это тоже ресемплер, только очень примитивный. Обычная "таймерная музыка" будет звучать шершаво, но терпимо, а вот ШИМ превратится в шум. С практической точки зрения это небольшая беда, потому что не так много ШИМ-ных программ написано для 8080. Но это неплохой бенчмарк качества ресемплера. Кроме того, качественные эмуляторы вдохновляют людей писать интересные вещи.
    Больше игр нет

  9. #6
    Banned
    Регистрация
    22.05.2011
    Адрес
    г. Дзержинск, Украина
    Сообщений
    6,841
    Спасибо Благодарностей отдано 
    483
    Спасибо Благодарностей получено 
    658
    Поблагодарили
    512 сообщений
    Mentioned
    10 Post(s)
    Tagged
    0 Thread(s)

    По умолчанию

    Цитата Сообщение от CityAceE Посмотреть сообщение
    Пока я веду речь о простом однобитном звуке.
    например можно сделать так

    сразу эмулировать работу динамика


    установка бита вывода звука

    включает инкремент переменной громкости каждую команду на Коэфицент*Количество тактов команды
    у инкрементилки ограничение по максимальному значению
    превышая которое будет установленно обратно максимальное значение


    сброс бита звука
    включает декрементилку переменной громкости каждую команду на Коэфицент*Количество тактов команды
    у декрементилки ограничение по минимальному уровню
    превышая которое будет установленно обратно минимальное значение


    после такого можно будет писать в буффер намного меньше значений для более простого ресемплирования (тк алиасинг серанвно будет)
    или может даже не репрессировать вообще
    (если не будет беспокоить писк)



    или же можно организовать подобную эмуляцию динамика над большим буффером
    возможно это будет более оптимальным вариантом


    меняя коэфициент методом научного тыка
    можно будет менять частоту среза высоких
    и подобрать более подходящий тембр


    ну и для лучшего эффекта еще нужно эмитировать конденсатор в цепи

    интуитивно понятная картинка как оно работает


    правда тогда нужно усложнять предыдущий алгоритм
    хотя можно забить и пустить и пост обработкой к первому
    Последний раз редактировалось NEO SPECTRUMAN; 19.04.2020 в 16:22.

  10. Этот пользователь поблагодарил NEO SPECTRUMAN за это полезное сообщение:

    CityAceE (19.04.2020)

  11. #7
    Administrator Аватар для CityAceE
    Регистрация
    13.01.2005
    Адрес
    г. Москва
    Сообщений
    4,574
    Записей в дневнике
    7
    Спасибо Благодарностей отдано 
    399
    Спасибо Благодарностей получено 
    1,207
    Поблагодарили
    394 сообщений
    Mentioned
    48 Post(s)
    Tagged
    0 Thread(s)

    По умолчанию

    Цитата Сообщение от NEO SPECTRUMAN Посмотреть сообщение
    например можно сделать так
    Да, тоже вариант. Спасибо.
    С уважением, Станислав.

  12. #8
    Guru
    Регистрация
    24.01.2008
    Адрес
    Уфа
    Сообщений
    3,847
    Спасибо Благодарностей отдано 
    84
    Спасибо Благодарностей получено 
    229
    Поблагодарили
    167 сообщений
    Mentioned
    9 Post(s)
    Tagged
    0 Thread(s)

    По умолчанию

    Цитата Сообщение от svofski Посмотреть сообщение
    Обычная "таймерная музыка" будет звучать шершаво, но терпимо, а вот ШИМ превратится в шум.
    А если учесть интересную идею CityAceE-а:
    Цитата Сообщение от CityAceE Посмотреть сообщение
    менять частоту виртуального процессора - 45 * 44 100 = 1 984 500 Гц
    Может будет не так уж всё и плохо?

  13. #9
    Guru Аватар для svofski
    Регистрация
    20.06.2007
    Адрес
    С.-Петербург
    Сообщений
    4,116
    Спасибо Благодарностей отдано 
    793
    Спасибо Благодарностей получено 
    658
    Поблагодарили
    403 сообщений
    Mentioned
    22 Post(s)
    Tagged
    0 Thread(s)

    По умолчанию

    Цитата Сообщение от b2m Посмотреть сообщение
    Может будет не так уж всё и плохо?
    Дело по-моему не в кратности частот, а в подходе с нарезанием на кусочки. На стыках кусочков получаются звуки, которых нет. От этого получается хрюкотанье, которое практически невозможно отфильтровать.

    Если я правильно понимаю метод NEO SPECTRUMAN-а, это суть интегратор. Интегратор годится для преобразования ШИМ в ИКМ, то есть то, что мы хотим слышать. Выход интегратора можно семплировать в буфер с частотой аудиокарты и такой результат имеет шансы получше. Не попробуешь — не узнаешь.
    Больше игр нет

  14. #10
    Banned
    Регистрация
    22.05.2011
    Адрес
    г. Дзержинск, Украина
    Сообщений
    6,841
    Спасибо Благодарностей отдано 
    483
    Спасибо Благодарностей получено 
    658
    Поблагодарили
    512 сообщений
    Mentioned
    10 Post(s)
    Tagged
    0 Thread(s)

    По умолчанию

    Цитата Сообщение от svofski Посмотреть сообщение
    Выход интегратора можно семплировать в буфер с частотой аудиокарты
    до
    НО
    если кто то будет пытаться делать ШИМ на бипере
    высокая не кратная частота ШИМ-а серавно пролезет
    а если не ресемплиовать хоть немного хотябы простое 2х
    вылезет алисаниг
    хотя и тихий


    самое главное
    что такая шняга легко реализуется целочисленно


    - - - Добавлено - - -

    Цитата Сообщение от svofski Посмотреть сообщение
    Дело по-моему не в кратности частот,
    в кратности тоже
    эмуляторы изза этого любят пищать

    ну и как итог
    don't use emulators, their beeper emulation SUXX


    а "частота нарезки" не такая высокая чтобы пищать
    Последний раз редактировалось NEO SPECTRUMAN; 20.04.2020 в 17:11.

Страница 1 из 2 12 ПоследняяПоследняя

Информация о теме

Пользователи, просматривающие эту тему

Эту тему просматривают: 1 (пользователей: 0 , гостей: 1)

Похожие темы

  1. Нужна помощь в эмуляции звука
    от denpopov в разделе Программирование
    Ответов: 102
    Последнее: 02.05.2017, 23:44
  2. Код эмуляции i8080 на С
    от medvdv в разделе Эмуляторы отечественных компьютеров
    Ответов: 15
    Последнее: 27.03.2015, 03:43
  3. цифровой звук на AY - научный подход
    от SMT в разделе Программирование
    Ответов: 21
    Последнее: 15.02.2013, 14:04
  4. Общий каталог ZX-Soft"a
    от Vitron в разделе Разный софт
    Ответов: 6
    Последнее: 26.11.2006, 07:39

Ваши права

  • Вы не можете создавать новые темы
  • Вы не можете отвечать в темах
  • Вы не можете прикреплять вложения
  • Вы не можете редактировать свои сообщения
  •