Цель состоит в том, чтобы реализовать своего рода цифровое пианино на FPGA.
До сих пор мне удавалось производить отдельные заметки с помощью счетчиков. По сути, я генерирую прямоугольную волну определенной частоты, которая соответствует музыкальной ноте (конечно, для этого я полагаюсь на частоту часов, но это не проблема).
Как я могу разработать схему, которая может создавать перекрытие нескольких нот? По сути, я хочу иметь возможность одновременно воспроизводить 2 звука разных частот.
Когда я был подростком в 1980-х, у меня был компьютер Apple II+, у которого был выход динамика, аналогичный динамику IBM PC. Доступ к размещенному в памяти расположению порта ввода-вывода приводил к переключению выхода, подключенного к динамику.
Я написал программу на машинном языке, которая проигрывала трезвучия: три одновременные ноты. Справочная таблица преобразовывала значения нот (индексированные по полутонам) в значения счетчиков. Подход был прост: инициализировать три счетчика и запускать их независимо друг от друга в большом цикле. На любой итерации, когда хотя бы один из счетчиков перевернулся, переключите динамик.
Эта подпрограмма в сочетании с программой BASIC для обработки данных воспроизводила очень хорошо звучащую последовательность синтезаторных аккордов из Van Halen's Jump .
Это уникальный звук. Есть искажения, но разделение нот вполне четкое.
Тембровые вариации можно получить, кстати, с изменением скважности. Кажется, я припоминаю, что это переводится в воспринимаемый объем.
Это во многом зависит от типа оборудования, которое у вас есть.
Если у вас есть только 1-битный выход на FPGA, вы можете передискретизировать аудиосигнал (1 МГц или более) и использовать ШИМ или дельта-сигма модулятор, эффективно генерируя сигнал с переменной амплитудой (вы можете добавить фильтр нижних частот, простой RC-цепи достаточно).
Затем вы можете добавить свои синтезированные сигналы (синусоидальный, квадратный, треугольный...) и генерировать полифонические звуки. Например, с 8-битным (со знаком) сумматором установите амплитуду двух генераторов прямоугольных импульсов на +50/-50.
Один простой способ состоит в том, чтобы взять каждый выход счетчика, пропустить его через резистор, а затем соединить другой конец резисторов вместе. Теперь отдельные выходные сигналы счетчика будут ослаблены, а конечный результат будет суммой выходных сигналов счетчиков.
Два способа (которые я могу придумать):
Если вы имеете дело только с одним цифровым выходом и генерируете прямоугольные волны, самый простой способ сделать это — иметь два (или n) счетчиков на каждой желаемой частоте и выполнять XOR их выходов вместе перед выводом их на вывод. Это дает результат, эквивалентный подходу Kaz к переключению.
Пол92
Каз
Фотон