Звуковой синтезатор efm8: воспроизведение мелодий через usb

Звуковой синтезатор efm8: воспроизведение мелодий через usb
Звуковой синтезатор efm8: воспроизведение мелодий через usb
Anonim

Звуковой синтезатор EFM8: воспроизведение мелодий через USB

Часть 3 в разделе «Как создать звуковой синтезатор на базе EFM8».

Предыдущие статьи в серии

Эта статья является частью полного проекта по созданию синтезатора на базе EFM8. Начните со следующего:

  • Часть 1: от квадратной волны до синусоидальной волны
  • Часть 2: Вождение спикера

Требуемое оборудование / программное обеспечение

  • Плата оценки SLFK2000A EFM8
  • Интегрированная среда разработки Simplicity Studio
  • Scilab
  • Компоненты, перечисленные в спецификации
Описание Количество Digi-Key p / n
макетировать 1 377-2094-ND
Провода перемычки между розетками 4 1471-1231-ND
Напряжение питания 5 В переменного / постоянного тока 1 1470-2771-ND
Конденсаторы 0, 1 мкФ 5 399-4266-ND
Фильтр нижних частот с переключаемым конденсатором нижнего порядка 1 LTC1063CN8 # PBF-ND
Операционный усилитель общего назначения 2 LT1638CN8 # PBF-ND
Аналоговый буфер питания 1 LT1010CN8 # PBF-ND
2 мкФ конденсатор 1 490-8835-ND
Резисторы 10 кОм 2 10KQBK-ND
100 Ом резистор 1 100QBK-ND
8 Ом, 1 Вт динамик 1 GF0771-ND

Обзор проекта

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

Мы достигнем этого, установив USB-соединение виртуального COM-порта (VCP) между EFM8 и Scilab (см. Эту статью для вводной информации о Scilab, и в этом представлена библиотека последовательного порта Scilab). Сценарий Scilab, используемый в этом проекте, обеспечивает простой интерфейс командной строки, посредством которого пользователь может запускать и останавливать воспроизведение звука, устанавливать темп и вводить информацию музыкальной заметки для простой мелодии.

Scilab

Вот сценарий:

Image
Image

Скачать код

Во-первых, Scilab настраивает и открывает VCP. Если по какой-либо причине библиотека последовательного порта не может установить соединение с EFM8, консоль Scilab сообщит, что COM-порт не может быть открыт, а затем «прервать», то есть слово Scilab использует для «прекращения выполнения сценария и возврата к нормальной работе «. Если соединение успешно установлено, скрипт вводит бесконечный цикл ввода-вывода, в котором в окне консоли Scilab предлагается ввести строку символов для отправки в EFM8. Чтобы отправить команду, просто введите соответствующие символы и нажмите клавишу ввода. Чтобы разбить цикл и выйти из сценария, вы нажимаете клавишу ввода без ввода каких-либо других символов (обратите внимание, что соединение VCP закрыто, а последовательная библиотека «разгружена» до завершения сценария).

Прошивка EFM8 распознает четыре типа команд: воспроизведение звука («P»), остановка звука («S»), установка темпа («T ###») и создание мелодии (формат команды, обсуждаемый ниже). Команды воспроизведения и остановки звука включают или выключают звуковые сигналы и прямоугольные волны с фильтром, не нарушая при этом нормальной работы прошивки. Команда set tempo используется для управления скоростью воспроизведения; темп вводится в бит в минуту (BPM). Прошивка в настоящее время ограничивает темп между 60 и 180 BPM, поэтому числа выше или ниже этого диапазона будут изменены на 180 или 60 соответственно EFM8.

Способ создания мелодии может казаться несколько загадочным, но его легко реализовать и на самом деле может быть довольно быстрым и интуитивным, если вы смотрите на кусок музыки во время ввода символов. Мелодия вводится как последовательность пар символов, содержащая букву (которая представляет собой музыкальную ноту) и число (которое представляет собой продолжительность воспроизведения ноты). В настоящее время прошивка поддерживает целые ноты, половинные ноты, четвертные ноты и восьмые ноты.

Image
Image

При вводе мелодии вы используете «1» для целой ноты, «2» для половины ноты, «4» для четвертной ноты и «8» для восьмой ноты. Для самих заметок вы используете соответствующую букву. Интерфейс командной строки поддерживает две октавы, начинающиеся с C и заканчивающиеся на B (без острых предметов или квартир). Ноты в нижней октаве обозначаются строчными буквами, а те, что указаны в верхней октаве, обозначаются прописными буквами. Поэтому, если вы хотите воспроизвести все ноты, поддерживаемые интерфейсом, в порядке возрастания и с каждой нотой, составляющей четверть ноты, вы должны ввести «c4d4e4f4g4a4b4C4D4E4F4G4A4B4». Примечание. Текущая прошивка поддерживает ноты только во второй октаве E; более высокие ноты не нужны для демонстрационных мелодий, и эти примечания будут постепенно более ослаблены фильтром нижних частот RC, как описано в предыдущей статье. Кроме того, в какой-то момент сигнал синхроимпульса станет ненадежным, поскольку прерывания PCA будут происходить так часто, что процессор EFM8 не сможет последовательно обновлять регистр захвата / сравнения. Вы можете, конечно, расширить прошивку, чтобы включить эти более высокие ноты, но вам нужно следить за квадратной волной фильтра-часов, и вам может потребоваться изменить фильтр нижних частот RC для более высокой частоты среза.

Дополнительные сведения о интерфейсе командной строки:

  • Для команд темпа представление ASCII значения темпа преобразуется в однобайтовое число, так что EFM8 не нужно выполнять это преобразование. Другие команды передаются непосредственно в EFM8.
  • Воспроизведение автоматически включается при отправке команды мелодии.
  • Все команды повторяются EFM8, как показано ниже в примере командной строки.
  • Вы можете указать остаток (т. Е. Период, в котором не воспроизводится нота) с использованием «r», за которым следуют «1», «2», «4» или «8»; число указывает продолжительность остального как целое, половину, четверть или восьмую ноту.
  • Вы можете установить темп в любое время, но скорость воспроизведения не изменится, пока вы не введете новую мелодию (или повторно введите текущую мелодию). Темп по умолчанию - 120 BPM.
  • Нажатие клавиши со стрелкой вверх в командной строке позволяет вам циклически перемещаться по ранее введенным строкам; это очень полезно, когда вы отправляете длинные команды мелодии и просто хотите изменить одну ноту, или если вам нужно повторно ввести предыдущую мелодию.
  • Для простоты все команды в настоящее время ограничены одним 64-байтовым USB-пакетом. Каждая нота требует двух байтов, поэтому максимальная длина мелодии составляет 32 ноты.

Ниже приведен пример правильного использования интерфейса командной строки. Сценарий выполняется, и EFM8 запрограммирован на воспроизведение восходящего C-масштабного масштаба со всеми четвертными нотами, а затем с уменьшающейся шкалой C со всеми восьмыми нотами. Затем темп уменьшается до 60 BPM, а затем увеличивается до 180 BPM. Наконец, воспроизведение отключено, а затем снова включено до завершения сценария. Вы заметите, что эховые символы для команд темпа выглядят неправильно, но на самом деле они - Scilab отображает символ ASCII, соответствующий однобайтовому номеру темпа, полученному EFM8.

Image
Image

Конфигурация USB

В этой статье представлен обзор USB-связи с использованием библиотеки SiLabs VCPXpress, а также важные аспекты добавления функций VCP в проект Simplicity Studio. Здесь мы кратко рассмотрим все шаги, связанные с включением связи VCP в нашу прошивку:

1. Скопируйте «VCPXpress.h», «VCPXpress.lib», «descriptor.c» и «descriptor.h» в каталог проекта:

Image
Image

2. Добавьте правильный путь включения в свойства проекта:

Image
Image

3. Добавьте библиотеку VCPXpress в свойства проекта:

Image
Image

4. Вставьте исходный файл, содержащий код для взаимодействия с библиотекой VCPXpress и обработки USB-пакетов:

Image
Image

5. Вставьте код для новых прототипов функций, глобальных переменных и определений препроцессора (ошибки сборки помогут вам найти что-нибудь, что вы, возможно, пропустили), и включите «VCPXpress.h» и «descriptor.h» в любые исходные файлы, которые их требуют:

Image
Image

6. Добавляйте вызовы к USB_Init () и API_Callback_Enable () после вызова функции инициализации оборудования:

Image
Image

7. Чтобы подавить предупреждения компоновщика, скопируйте «OVERLAY (? PR? _USB_WRITEFIFO? EFM8_USBDEP! *, ? PR? _USBD_READ? EFM8_USBD! *, ? PR? _USBD_WRITE? EFM8_USBD! *, ? PR? _VCPXCORE_WRITE? VCPXPRESS! *)" В " Дополнительные флаги "в настройках компоновщика:

Image
Image

Приоритет прерывания

Единственное изменение в конфигурации периферийного / прерывания EFM8 - это тонкое, но важное: прерывание PCA было настроено на высокий приоритет.

Image
Image

Первоначально выходной сигнал прямоугольной формы с фильтрами был серьезно ненадежным, по-видимому, потому, что прерывания с более высоким приоритетом, связанные с библиотекой VCPXpress, вытесняли прерывания PCA. Эта модификация настроек приоритета гарантирует, что прерывания PCA будут обработаны своевременно.

Функциональные данные

Прошивка создает мелодии, преобразуя командную строку в последовательность заметок и соответствующую последовательность отсчетов Timer3, причем каждая последовательность хранится в отдельном массиве:


void StoreNewMelody() { unsigned char x, y; y = 0; for(x = 0; x < USBBytesReceived; x += 2) { NotesSequence(y) = USBRxPacket(x); switch(USBRxPacket(x+1)) { case '1': Timer3Counts_Sequence(y) = WholeNoteCounts; break; case '2': Timer3Counts_Sequence(y) = HalfNoteCounts; break; case '4': Timer3Counts_Sequence(y) = QuarterNoteCounts; break; case '8': Timer3Counts_Sequence(y) = EighthNoteCounts; break; } y+; } NumberofNotes = y; CurrentNoteIndex = NumberofNotes - 1; //start playback at the beginning of the melody PLAYorSTOP = PLAY; }

Количество отсчетов Timer3, используемых для целого, половины, четверти или восьмой ноты, рассчитывается при приеме заданной команды темпа:


void SetTempo(unsigned char TempoBPM) { if(TempoBPM > 180) TempoBPM = 180; else if(TempoBPM < 60) TempoBPM = 60; QuarterNoteCounts = ((float)60/TempoBPM) * 10000; WholeNoteCounts = QuarterNoteCounts*4; HalfNoteCounts = QuarterNoteCounts*2; EighthNoteCounts = QuarterNoteCounts/2; }

Эти расчеты предполагают, что длительность четвертной ноты - один такт, и, следовательно, целая нота - 4 удара, половина ноты - 2 удара и восьмая нота - половина удара. Таким образом, с темпом 60 BPM ноты будут иметь следующие длительности:

Image
Image

В основном цикле while программа циклически проходит через каждый элемент в массиве музыкальной ноты и соответственно устанавливает соответственно звуковой сигнал и тактику синхроимпульсов, а затем использует соответствующее значение в массиве Timer3-counts для реализации соответствующей задержки.


while(1) { for(CurrentNoteIndex = 0; CurrentNoteIndex < NumberofNotes; CurrentNoteIndex+) { REPEATED_NOTE = FALSE; if(CurrentNoteIndex < (NumberofNotes - 1)) { if(NotesSequence(CurrentNoteIndex) == NotesSequence(CurrentNoteIndex + 1)) REPEATED_NOTE = TRUE; } switch(NotesSequence(CurrentNoteIndex)) { case 'c': Current_SoundSignal_Increment = SOUND_C5_INCREMENT; Current_FilterClock_Increment = FILTCLK_C5_INCREMENT; break; case 'd': Current_SoundSignal_Increment = SOUND_D5_INCREMENT; Current_FilterClock_Increment = FILTCLK_D5_INCREMENT; break; case 'e': Current_SoundSignal_Increment = SOUND_E5_INCREMENT; Current_FilterClock_Increment = FILTCLK_E5_INCREMENT; break; case 'f': Current_SoundSignal_Increment = SOUND_F5_INCREMENT; Current_FilterClock_Increment = FILTCLK_F5_INCREMENT; break; case 'g': Current_SoundSignal_Increment = SOUND_G5_INCREMENT; Current_FilterClock_Increment = FILTCLK_G5_INCREMENT; break; case 'a': Current_SoundSignal_Increment = SOUND_A5_INCREMENT; Current_FilterClock_Increment = FILTCLK_A5_INCREMENT; break; case 'b': Current_SoundSignal_Increment = SOUND_B5_INCREMENT; Current_FilterClock_Increment = FILTCLK_B5_INCREMENT; break; case 'C': Current_SoundSignal_Increment = SOUND_C6_INCREMENT; Current_FilterClock_Increment = FILTCLK_C6_INCREMENT; break; case 'D': Current_SoundSignal_Increment = SOUND_D6_INCREMENT; Current_FilterClock_Increment = FILTCLK_D6_INCREMENT; break; case 'E': Current_SoundSignal_Increment = SOUND_E6_INCREMENT; Current_FilterClock_Increment = FILTCLK_E6_INCREMENT; break; case 'r': SFRPAGE = PCA0_PAGE; PCA0CN0_CR = STOP; break; } //delay for the length of time corresponding to the current note SFRPAGE = TIMER3_PAGE; TMR3 = 0; while(TMR3 < Timer3Counts_Sequence(CurrentNoteIndex));

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


REPEATED_NOTE = FALSE; if(CurrentNoteIndex < (NumberofNotes - 1)) { if(NotesSequence(CurrentNoteIndex) == NotesSequence(CurrentNoteIndex + 1)) REPEATED_NOTE = TRUE; } //----------------------------------------------------- //then after the note has been played… //----------------------------------------------------- if(REPEATED_NOTE == TRUE) { SFRPAGE = PCA0_PAGE; PCA0CN0_CR = STOP; SFRPAGE = TIMER3_PAGE; TMR3 = 0; while(TMR3 < 200); } SFRPAGE = PCA0_PAGE; PCA0CN0_CR = PLAYorSTOP;

Скачать код

Этот метод позволяет нам реально использовать звуки «щелчок и поп», которые обычно являются неприятным аспектом аудиосхемы: быстрый щелчок или поп, сгенерированный при повторном включении прямоугольных волн, обеспечивает дополнительное определение бит между повторяющимися нотами, Тем не менее, мы не хотим слишком много кликов и поп-сигналов, поэтому конденсатор с блокировкой постоянного тока в цепи был уменьшен с 2 мкФ до 0, 1 мкФ, чтобы уменьшить эти артефакты, что частично объясняется связанными с ними переходными токами с конденсаторами зарядного фильтра.

Image
Image

Следующие видеоролики содержат две тестовые мелодии; соответствующие записи в командной строке указаны в подписях. Звук, создаваемый этой системой, кажется смутно напоминающим средневековую флейту, и соответственно были выбраны мелодии.

Мелодия: E4a4a2E4a4a4a8b8C4C4b4C4D4D8D8C4D4E4E8E8D4D4C4C4b2a4C4b4g4a2a2; Команда Tempo: T180

Команда Мелодии: d2a2e2f8e4d2a2C4D2C4a4b4g4a2r2a4D2D4C2a2g4f4e2c4d2a4g2f4e4d4c4d1; Команда Tempo: T120. Некоторые из примечаний в этом случае неаккуратные, потому что замена нескольких нот одного тона на одну длинную ноту позволила поместить всю мелодию в один 64-байтовый пакет.

Попробуйте этот проект сами! Получить спецификацию.