Цифровая схема для добавления нескольких частот

Цель состоит в том, чтобы реализовать своего рода цифровое пианино на FPGA.

До сих пор мне удавалось производить отдельные заметки с помощью счетчиков. По сути, я генерирую прямоугольную волну определенной частоты, которая соответствует музыкальной ноте (конечно, для этого я полагаюсь на частоту часов, но это не проблема).

Как я могу разработать схему, которая может создавать перекрытие нескольких нот? По сути, я хочу иметь возможность одновременно воспроизводить 2 звука разных частот.

Ответы (5)

Когда я был подростком в 1980-х, у меня был компьютер Apple II+, у которого был выход динамика, аналогичный динамику IBM PC. Доступ к размещенному в памяти расположению порта ввода-вывода приводил к переключению выхода, подключенного к динамику.

Я написал программу на машинном языке, которая проигрывала трезвучия: три одновременные ноты. Справочная таблица преобразовывала значения нот (индексированные по полутонам) в значения счетчиков. Подход был прост: инициализировать три счетчика и запускать их независимо друг от друга в большом цикле. На любой итерации, когда хотя бы один из счетчиков перевернулся, переключите динамик.

Эта подпрограмма в сочетании с программой BASIC для обработки данных воспроизводила очень хорошо звучащую последовательность синтезаторных аккордов из Van Halen's Jump .

Это уникальный звук. Есть искажения, но разделение нот вполне четкое.

Тембровые вариации можно получить, кстати, с изменением скважности. Кажется, я припоминаю, что это переводится в воспринимаемый объем.

Это во многом зависит от типа оборудования, которое у вас есть.

Если у вас есть только 1-битный выход на FPGA, вы можете передискретизировать аудиосигнал (1 МГц или более) и использовать ШИМ или дельта-сигма модулятор, эффективно генерируя сигнал с переменной амплитудой (вы можете добавить фильтр нижних частот, простой RC-цепи достаточно).

Затем вы можете добавить свои синтезированные сигналы (синусоидальный, квадратный, треугольный...) и генерировать полифонические звуки. Например, с 8-битным (со знаком) сумматором установите амплитуду двух генераторов прямоугольных импульсов на +50/-50.

Часть fpga не имеет значения. Я не использую фактический аудиовыход. Вместо него у меня обычный цифровой выход, к которому я подключаю динамик. Итак, единственное, что у меня есть, это прямоугольная волна, и я должен создать эту прямоугольную волну таким образом, чтобы она звучала как две перекрывающиеся музыкальные ноты. Меня также больше интересует фактическая схема, чем фактическая реализация.
"обычный цифровой выход". Что это такое? 8 бит? 16 бит? Подписано? Без подписи?
@Kaz, мне кажется, у него один цифровой выходной сигнал (1 бит), и он использует его для управления динамиком.

Один простой способ состоит в том, чтобы взять каждый выход счетчика, пропустить его через резистор, а затем соединить другой конец резисторов вместе. Теперь отдельные выходные сигналы счетчика будут ослаблены, а конечный результат будет суммой выходных сигналов счетчиков.

Два способа (которые я могу придумать):

  1. С ЦАП
    • Умножайте сигналы по отдельности, чтобы получить разные индивидуальные амплитуды.
    • Суммируйте сигналы, которые вы хотите объединить
    • Вывод n бит в n-битный ЦАП
    • Вы можете сделать простой ЦАП R2R самостоятельно, используя только резисторы.
  2. Без ЦАП, с одним выводом и фильтром нижних частот
    • Добавьте два сигнала
    • Модулируйте выход, используя дельта-сигма модуляцию
    • Выход через фильтр нижних частот (самый простой RC).

Если вы имеете дело только с одним цифровым выходом и генерируете прямоугольные волны, самый простой способ сделать это — иметь два (или n) счетчиков на каждой желаемой частоте и выполнять XOR их выходов вместе перед выводом их на вывод. Это дает результат, эквивалентный подходу Kaz к переключению.