Воспроизведение нот на pic

В данной статье мы рассмотрим каким образом можно проигрывать музыкальные ноты при помощи PIC-микроконтроллера. Музыкальные ноты представляют из себя обычные звуковые частоты. И если мы точно знаем частоту определенной ноты, то мы можем запрограммировать микроконтроллер для проигрывания этой ноты через один пин ввода/вывода и звукоизлучатель.

В данном проекте мы рассмотрим проигрывание популярной композиции Happy Birthday To You при помощи микроконтроллера PIC16F628A и пьезоизлучателя.

Немного теории

Итак, как мы выяснили выше, для того, чтобы воспроизвести какую-либо мелодию, необходимо знать звуковые частоты нот. Каждая нота проигрывается с определенной длительностью и между двумя нотами также должна быть определенная длительность паузы. В таблице ниже, приведены частоты нот, начиная с ноты До.

Ноты других октав могут быть получены путем умножения или деления данных частот на 2. Например нота До следующей октавы будет иметь частоту 524 Гц. Частоты всех нот можно найти в данной таблице.

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

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

В данном проекте мы выберем первый способ.

Схемотехника

Схема устройства очень проста. Вывод RB0 микроконтроллера PIC16F628A используется для генерирования прямоугольный импульсов заданной частоты. Т.к.

выводы микроконтроллера не могут выдерживать ток более чем 25 мА, то пьезоизлучатель нельзя напрямую подсоединять к выводу МК. Поэтому используется npn транзистор BC547.

Желательно, еще использовать RC-фильтр, но здесь, для упрощения схемы он не показан.

Программное обеспечение

Генерирование аудио-частот реализовать на mikroC Pro очень просто. В нем уже есть встроенная библиотека для работы со звуком. Библиотека содержит две основные функции:

Sound_Init(char *snd_port, char snd_pin): задает соответствующий вывод микроконтроллера для генерации звука, например:

Sound_Init(&PORTB,0) задаст пин RB0 для вывода звука.

Sound_Play(unsigned freq_in_hz, unsigned duration_ms): Генерирует прямоугольный сигнал

Частоты нот можно задать в массиве или сохранить как постоянный массив в памяти ROM-микроконтроллера. У композиции “Happy birthday to you” не слишком много нот и поэтому мы определим их в integer массив, на mikroC это будет выглядеть так:

/* Hap py Birth Day to you, Hap py birth day to C4 C4 D4 C4 F4 E4 C4 C4 D4 C4 G4 */ unsigned int notes[] = { 262, 262, 294, 262, 349, 330, 262, 262, 294, 262, 392, /* you, Hap py Birth Day dear xxxx Hap py birth F4 C4 C4 C5 A4 F4 E4 D4 B4b B4b A4 */ 349, 262, 262, 523, 440, 349, 330, 294, 466, 466, 440, /* day to you F4 G4 F4 */ 349, 392, 349 };

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

Ниже представлено видео воспроизведения нот на PIC:

Скачать исходный код проекта и прошивку

Оригинал статьи на английском языке (перевод Колтыков А.В. для сайта cxem.net)

Источник: http://shemopedia.ru/vosproizvedenie-not-na-pic.html

Как читать ноты (Урок 2)

На прошлом уроке нашего Самоучителя мы научились ориентироваться на фортепианной клавиатуре, познакомились с понятиями: интервал, тон, полутон, гармония, тональность, гамма.

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

Да, не буду вам врать — это не самые простые в освоении знания, и сначала вам придется тратить какое-то время, чтобы понять, какая нота на какой линии что обозначает, придётся осваивать местный аналог пунктуации: знаки пауз, длительности и тому подобное.

Но, опять же, результат не заставит себя ждать.

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

А с фортепиано без них будет действительно сложно.

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

Посмотрите внимательно на картинку ниже, на ней показано все настолько наглядно, насколько это только возможно. Первое, что вы увидите, – клавиатуру пианино и надписи над ней.

Октава – это разделённый на равные части звукоряд, одна октава начинается с ноты До и заканчивается также нотой Си, следующая после Си нота До будет относиться уже к следующей октаве.

Ниже вы видите скрипичный ключ – пока вы в основном будете работать с ним. Иначе он зовётся ключом Соль – нота, изображенная рядом с ним, как раз, как не трудно догадаться, Соль, важный нюанс – это соль первой октавы.

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

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

Второй используемый для фортепиано ключ – басовый,или ключ Фа (нота расположена рядом с ним).

Он применяется реже, чем скрипичный, и на первых порах вы не будете его активно применять, однако впоследствии, с усложнением партий, вам придется играть басовые линии, которые будут располагаться ниже малой октавы (субконтроктава → контроктава → большая октава → малая октава).

Бас – низкий звук, поэтому ключ используется инструментами с низким по высоте звучанием, такими, как бас-гитара, контрабас, фагот.

Важно: отличия в данном случае не просто косметические – на нотном стане ноты в басовом ключе будут писаться и располагаться по-другому, придётся запоминать их отдельно, но коснёмся басового ключа мы позже.

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

Такт – отрезок в произведении между двумя тактовыми чертами, расставляемыми перед так называемыми сильными долями в музыке.

Так изображается тактовая черта в середине произведения:

А так изображается последняя тактовая черта, на котором произведение завершается:

Сильная доля – кульминационный момент в отдельно взятом такте, он выделяется тем, что нота более громко сыграна, самое главное в ней то, что музыкант её подчеркивает и слушатель, пусть даже неосознанно, поймет, где завершился отрывок.

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

Каждый ваш кивок или удар ногой – это и есть доля в такте (если вы, конечно, не страдаете аритмией, а я в этом сомневаюсь).

Касаемо длительностей нот – их изображение будет гораздо проще запомнить, чем информацию, которую вы уже успели получить.

Продолжать можно при желании ещё очень долго. Сейчас вы имеете поверхностное представление о том, как выглядят ноты с разными длительностями, сейчас попробуйте вникнуть в самую суть…

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

Половинная = ½ целой

Четвертые = ½ половинной = ¼ целой

Восьмая =  ½ четверти = ¼ половинной = 1/8 целой

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

Целая = Половинная + Восьмая + Восьмая + Восьмая + Восьмая

Целая = Четвёртая + Восьмая + Половинная + Восьмая…

Как я уже писал, длительности не будут ограничиваться восьмыми или шестнадцатыми. 32е, 64е, даже 128е и далее (хотя это уже, скорее, из области фантастики).

Думаю, что вы уловили смысл.…

Внутри каждого такта может располагаться определенное число ритмических долей.

Такты — это как вагоны поезда, в которые может поместиться только определенное количество пассажиров, например 4 взрослых или 8 детей(размер 4/4).  То какое их количество может поместиться в такте указывает размер.

Итак, у нас  остался один завершающий штрих – размер такта.

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

Цифры, которые записываются после ключа, обозначают, каков размер такта, то есть как часто и в какой позиции вы будете слышать сильную долю.

Верхняя цифра размера — означает сколько в такте долей, а нижняя — какие они по длительности.

Параметры нижней цифры:

1 — целая

2 — половинная

4 — четвертная

8 — восьмая

16 — шестнадцатая

32 — тридцать вторая ит.д.

4/4 – это наиболее часто встречающийся размер, он принят эталонным. Когда я говорил о длительностях нот, то речь шла именно о размере 4/4х. Эти цифры означают, что в такте 4 доли и по длительности они четвертные.

Но помимо него есть и другие, причем достаточно нестандартные. Но пока не буду сильно вас перегружать, на первое время (а оно будет достаточно долгим) вам хватит этих трёх:

Чтобы было проще понять, то вот, к примеру, как выглядит в диаграмме такт в 2/4:

Как видите, весь такт является ½ от 4/4 и, соответственно, он в 2 раза меньше целой ноты, т.е. максимальным размером в ней будет половинная:

2/4 = 1 половинная = 2 четвертых = 4 восьмых

Сильной долей будет считаться каждый 2-й удар.

В ¾ все будет чуть-чуть сложнее:

¾ = 1 половинная + 1 четвертая = 3 четвёртых = 6 восьмых

Между прочим, в этом размере играется вальс! Но это не более, чем к вопросу о танцевальной музыке. Те, кто занимались танцами, меня поймут, да и вообще многие, думаю, не раз слышали эту, уже ставшую стереотипной, фразу: «Раз, два, три! Раз, два, три!». Да-да, это и есть ¾.

Но такой счет можно встретить и в размере 3/8, и здесь мы будем считать не четвертными, а восьмыми. Потому что верхняя цифра говорит нам о том, что в такте 3 доли, а нижняя, что по длительности они не четвертные, а восьмые.

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

Надеюсь, вы еще помните первый урок, где я рассказывал, как играются гаммы.

Мы разбирали До мажор (C dur), Фа мажор (F dur), Соль мажор (G dur). Теперь, получив новые знания, давайте посмотрим, как будут выглядеть эти гаммы (обойдёмся только без До мажора – там и так всё очевидно).

Фа мажор (F dur)

Соль мажор (G dur)

Бемолями и диезами обозначены те ноты, которые вы будете играть на чёрных клавишах…. Впрочем, вы и так должны всё знать, вы ведь играли гаммы? Ведь играли же, правда? Учтите, я в вас верю!

Давайте подведём итог и посмотрим, что вы смогли усвоить:

Это простейшая песенка из детского сада: «Каравай-каравай, кого хочешь, выбирай!».

Включим дедукцию:

1) В самом начале песни всегда ставится ключ, в данном случае, это — скрипичный ключ.

2) После ключа стоят 2 диеза. Знаки альтерации показывают, в какой тональности играется произведение. В данном случае диезы на нотоносце стоят на линейках До второй октавы и Фа второй октавы. Из этого делаем вывод, что песня играется в тональности Ре мажор (вам простительно пока этого не знать, эту гамму на уроках я пока не затрагивал).

3) 2/4 – вы видите размер такта, на который вы должны ориентироваться и не превышать его пределов. Каждая сильная доля – вторая.

4) Значок четвертной паузы – первая четверть песни должна пройти без сопровождения фортепиано.

5) Две восьмые ноты Ре первой октавы.

6) Тактовая черта.

7) Начало следующего такта: 2 «восьмушки» ноты Соль первой октавы, 2 восьмые Си первой октавы.

Если ваши мысли совпали с вышеописанным, то спешу вас поздравить, вы двигаетесь в верном направлении. Если же у вас не все сразу получилось, то не расстраивайтесь – этот материал достаточно сложен для освоения с нуля…. Но, как говорится, главный способ чему-то научиться – это практика.

Для начала играйте по нотам простые песни, и, что важно, старайтесь пропевать читаемые вами ноты. Желательно при этом, чтобы рядом с вами был человек со знаниями и хорошим слухом, ибо если вы будете «лажать», то это будет только вам во вред.

Если вы уверены в собственном слухе, то тогда дерзайте… В крайнем случае вы можете ориентироваться на ваше пианино  — оно не даст вам соврать голосом.

Постепенно,  если вы будете петь и играть даже те же самые гаммы, ваш профессиональный уровень поднимется на куда более высокий уровень, и вы будете читать ноты гораздо увереннее. Вы ведь помните, что самое главное в здании – это фундамент. Насколько крепко вы его заложите, настолько вам будет проще жить в будущем. А пока… Терпения вам, друзья мои, терпения!

Сегодня в  качестве бонуса предлагаю вам потренироваться на определение нот с помощью вот этой обучающей программы на знание нот.

Наш следующий, третий урок, будет посвящен гаммам, интервалам и другим понятиям, о которых будущему пианисту необходимо знать.

(1

Источник: https://ProPianino.ru/kak-chitat-noty

Может ли компьютер распознавать ноты в звуках?

В свое время я решал подобную задачу — мне понравилась партия фортепиано в одной песне, простая, но красивая, и я решил научиться ее играть. Т.к. слухом не обладаю и подбор был бы слишком мучительным, подошел с науxной стороны: спектрометр spectraPLUS + таблица соответствия частот с нотами (октавная система, бемоли и диезы на калькуляторе считать) + редактор guitarPro.

В спектрометре можно или в прямом эфире во время отлавливать на графике «частота-амплитуда» наиболее резво-меняющиеся «горбики» (амплитуду), смотреть частоту вершины и сверять с нотной таблицей:или, что еще удобней, в таком виде, где с введение цветовой компоненты получается спектр «частота-амплитуда-время», что позволяет не отматывать постоянно на нужные моменты, вся информация сохраняется:сразу видно (красные области), в какой момент какая нота(т.е. пока частота) прозвучала. Если нотной грамотой не владеешь, то в guitarPro включаешь отображение клавиатуры, смотришь в той же википедии, где какая нота находится, и тыкаешь. Однако темп, размер, длина ноты и прочие плюшки придется уже самому крутить (если заморочиться, то по последней картинке можно отловить и темп(по расстоянию между одинаковыми фрагментами), и длину ноты (длина полоски или расстояние между ними)).С голосом, правда, будет тяжело, ибо значения частот вряд ли будет дискретно, и будет та еще пляска.

Тьфу, только сейчас вспомнил. это был hard-way. Easy way — программа AmazingMIDI, которая раскладывает wav на миди (множество параметров помогут подобрать баланс). Миди потом можно импортировать в тот же guitarPro

Ноты компьютер различить может — так, например, работают все програмные тюнеры для гитары и др. А вот для голоса я таких не знаю… В смысле именно чтоб напеть, а она бы их сразу в аппликатуру превратила.

Для написания своей музыки для начала попробуйте GuitarPRO. Там можно записать партию (по нотам, правда) а потом прослушать как она будет звучать на разных инструментах. Но нужно вникнуть в теорию музыки.

Вот.

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

Замечу, голос нужен очень хороший. Как-то ради шутки пели ноту «ля» в хороший тюнер — удержать ноту на определенной высоте удавалось не более доли секунды, потом либо выше, либо ниже. Программные решения есть, но проще напеть эту мелодию и отправить её знакомому музыканту, если таких нет — я могу вам в этом помочь.

Либо самому изучать музыку.

Источник: https://toster.ru/q/3800

Музыкальная шкатулка на PIC16F753

Меня в свое время очень впечатлил этот пост о создании светомузыкального устройства на микроконтроллере в подарок любимой. И однажды пришло мое время сделать такой подарок.

Учитывая отличия от автора упомянутого проекта в навыках и инструментарии; будучи сильно ограничен во времени подготовки (3-4 дня), я пошел другим путем и разработал свое музыкальное устройство для установки в купленную в сувенирном магазине шкатулку.

Оно отличается более простой схемой и легкостью изготовления. В статье описываются подробности моего проекта и их мотивация. Осторожно, фотографии (всего около 1Мб).

Схема

Как видите, деталей очень мало. Питание в диапазоне +3..+4.8В от трех батареек типа AAA подходит без применения стабилизаторов как микроконтроллеру D1 (PIC16F753), так и усилителю DA1 (TDA7052A).

Данная микросхема усилителя является уникальной в своем роде, потому что среди своих аналогов она требует минимальное количество внешних элементов.

Применение усилителя мощности необходимо: при попытке подключить выход микроконтроллера напрямую к динамику, достаточную громкость получить не удастся.

Для работы усилителя необходим конденсатор C1 емкостью 220мкФ. Без конденсатора нельзя: если внутреннее сопротивление источника питания недостаточно мало, то звучать будет тихо и с сильными искажениями. Также необходим конденсатор C4 для развязки аудиосигнала по постоянному току.

Подстроечным резистором R2 регулируется громкость. R1 ограничивает диапазон регулировки. Совместно с конденсатором C3 он также образует фильтр низких частот. В принципе C3 можно не ставить.

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

TDA7052A (в отличие от TDA7052) имеет отдельный вход управления громкостью путем подачи на него соответствующего напряжения (на схеме не показан). Но попытка использовать его нисколько не упрощает схему и не улучшает ее работу. К счастью, при оставлении этого входа неподключенным нормальная работа усилителя не нарушается.

Пару слов о выборе микроконтроллера. Самый главный критерий — диапазон напряжения питания. Когда батарея почти разряжена, напряжение на ней проседает до 3В (по 1В на элемент). В свежем же состоянии напряжение может подниматься до +4.8В и даже более.

К сожалению, более современные 16-битные микроконтроллеры, имеющие высокую скорость и много памяти, обычно требуют питание в диапазоне +2.7..+3.6В. Чтобы понизить напряжение, пришлось бы применять стабилизатор, причем не любой, а с малым падением напряжения (Low Drop-out), учитывая напряжение на батарее под конец ее службы.

Я решил не усложнять. Из контроллеров фирмы Microchip (с ними у меня больше всего опыта и имеется программатор), поэтому, подходят только 8-битные. Также можно было бы использовать 16-битные из серии PIC24F. В следующей музыкальной шкатулке я, наверное, так и сделаю.

Все-таки PIC16F753 очень уж тесноват как по скорости, так и по объему памяти. Но зато у него имеется встроенный 9-битный ЦАП, что очень подходит для синтеза звука.

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

Сборка

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

Дома нет для этого условий, а на заводе заказывать — слишком долго и дорого. Поэтому собирал схему на макетной плате. Удалось вырезать лобзиком кусок платы по размерам шкатулки. Размеры и форма предопределили компоновку деталей.

Вот фотка на промежуточных стадиях сборки:

Проводами на время написания и отладки прошивки подключен программатор. Микросхемы поставил на панельках, и не зря: из купленных на радиобазаре двух микросхем усилителя одна оказалась битой. Удалось избежать ее перепайки.
Вид с обратной стороны платы.

Как видите, длинные или пересекающиеся соединения выполнены проводом МГТФ, а короткие — обрезанными ножками от конденсаторов и резисторов. После проверки работоспособности схемы на тестовой прошивке можно приступать к разработке и отладке основной программы.

Подробнее о ней ниже.

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

Из черного картона по форме шкатулки вырезаем и сгибаем такую конструкцию.

Прорезаем ножиком дырку для выключателя. Шилом протыкаются дырочки над динамиком. Далее приклеиваем выключатель к картонке и динамик на штатное место платы:Окончательный вид открытой шкатулки:

Программа для PIC и подготовка музыки

1. Синтез звука

Имея 9-битный ЦАП, в принципе, можно получить достаточно сложный звуковой сигнал, однако в случае PIC16F753 возможности ограничены из-за малого размера памяти программ микроконтроллера — всего 2048 слов.

Как показывает опыт, даже простая программа-проигрыватель, написанная на ассемблере и оптимизированная по размеру кода, занимает около 1000 слов, так что для нот остается совсем немного. И совсем ничего не остается для хранения сэмплов при использовании такого метода синтеза звука, как Wavetable.

Читайте также:  Стабилизатор напряжения на микросхеме кр142ен19 с защитой

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

, например, сборник «This is Tritone 2» (также имеется на Youtube). Этот метод я и реализовал в шкатулке. Удалось реализовать полифонический звук: 4 независимых звуковых канала. Можно управлять громкостью каждого канала.

Находим частоту, соответствующую нужной ноте, по формуле равномерной темперации: f = 440*2^(n/12), где n — номер ноты в полутонах, n=0 соответствует «ля» первой октавы.

Так как у нас 4 канала, то нужно одновременно генерировать 4 сигнала и суммировать их перед выводом. Наиболее распространенное решение — использовать для всех каналов общую частоту дискретизации.

При этом процессор через равные промежутки времени вычисляет выходной отсчет для каждого канала. Полученные значения суммируются и подаются на ЦАП.

Желаемые периоды прямоугольных сигналов, в общем случае, не являются кратными периоду дискретизации. Скажем, для ноты «ля» второй октавы у нас n=12, f=880 Гц. При частоте дискретизации Fs=27777.8Гц каждый период сигнала должен длиться ~31.57 выходных отсчетов, что нереализуемо. Здесь есть три выхода:

  1. Округлить период до целого числа отсчетов. При этом получаемый период будет отличаться от заданного, т.е. музыка будет фальшивить.
  2. Варьировать длительность периода в пределах плюс-минус одного отсчета так, чтобы средний период получаемого сигнала был равен 1/f. С точки зрения теории обработки сигналов это эквивалентно интерполяции методом ближайшего соседа. В результате в звуке возникают существенные негармонические искажения, в спектре появляются пики на посторонних частотах. На слух сигнал просто становится «грязным».
  3. Провести интерполяцию по Шеннону. Этот подход исключает фальшь и дает наилучшее качество звука, но в 8-битных микроконтроллерах неприемлем из-за сложности вычислений.

Так что на практике можно выбирать между вариантами 1) и 2). Оба они используются при программном синтезе многоканальной музыки на 1-битном звуковом выходе в таких компьютерах, как ZX Spectrum. Я лично предпочитаю вариант 1). При достаточно высокой частоте дискретизации, на не слишком высоких нотах, округление частоты незначительно, и фальшь практически незаметна.

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

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

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

программа на Матлабеfs = 2e6/72; notes = -24:26;
f = zeros(size(notes));
d = zeros(size(notes));
fa = zeros(size(notes));
ndifs = zeros(size(notes));
for i=1:length(notes) f(i) = 440*2^(notes(i)/12); k = round(fs/f(i)); fa(i) = fs/k; na = 12*log2(fa(i)/440); ndifs(i) = na-notes(i); d(i) = k; fprintf('%10.1f %10.1f %3d %4.2fn',f(i),fa(i),notes(i),ndifs(i));
end
plot(ndifs);
ylim([-0.5 0.5]); fprintf('nn'); for i=1:length(notes) fprintf('tretlwtH''%02X''n',d(i)); end

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

В этих логарифмических единицах и оценивается отклонение, график которого выводится на экран:

Можно поэкспериментировать, меняя частоту дискретизации, то есть количество тактов процессора, приходящихся на один ее период.

Эмпирически я подобрал коэффициент 72, который дает минимально достижимые отклонения нот в заданном диапазоне.

2. Архитектура прошивки

У PIC16F753 имеется три таймера, но только таймер 2 можно запрограммировать на генерацию прерываний с заданным периодом. С его помощью получаем прерывания на частоте дискретизации звука, т.е. каждые 72 такта процессора. Процедура обработки прерываний вычисляет очередное значение для вывода на ЦАП.

Чтобы избежать искажений звука, необходимо обновлять уровень на ЦАП через строго равные промежутки времени. Так как вычисления могут занимать различное время в зависимости от состояния программы, здесь есть два варианта. Первый — «подравнять» все ветки вычислений, чтобы они исполнялись за одинаковое число тактов.

Второй — сразу вывести в ЦАП значение, рассчитанное во время обработки предыдущего прерывания, а потом уже рассчитать значение для вывода в следующем прерывании. Я избрал второй путь.

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

По прерываниям работает генерация стационарных сигналов — прямоугольников неизменной частоты, скважности и амплитуды. Эти параметры хранятся в соответствующих ячейках памяти. При работе прошивки прерывания никогда не запрещаются.

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

Получается такой же режим работы, как если бы в системе был звуковой чип, наподобие Atari Pokey или AY-3-8910: эти чипы тоже формируют на каждом канале стационарные сигналы до тех пор, пока процессор не изменит значения параметров во внутренних регистрах этих чипов.

Обновление параметров генерации осуществляется процедурами, работающими в фоновом режиме (т.е. между прерываниями). Здесь я задействовал таймер-1 для обеспечения периодичности вызова процедуры обновления параметров — 50Гц. Такая же или близкая частота используется для этих целей в музыкальных проигрывателях на 8-битных компьютерах.

В остальном архитектура прошивки определяется представлением музыки в памяти. Я пошел по принципу трекерной музыки, по которым в основном создавалась музыка на 8-битных компьютерах. Не буду вдаваться здесь в детали, материалов на эту тему много в интернете.

3. Подготовка музыки

Чип-музыку надо в чем-то редактировать, и на сегодняшний день один из наиболее легких путей — это использовать Open Modplug Tracker.

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

В результате создается трекерный файл в формате .it. Я также написал программу-конвертор, которая конвертирует ноты из it-файла в формат, распознаваемый моей прошивкой PIC16F753.

Конвертор ругается, если встретит в it-файле ноты за пределами диапазона или неподдерживаемые прошивкой команды. Инструменты из it-файла полностью игнорируются конвертором. Они нужны только для контроля звучания музыки во время редактирования.

Сэмплы прямоугольников различной скважности, которые нужны во время редактирования музыки, я сгенерировал специальными программами на Матлабе. Но это было проделано давно в рамках другого проекта — конверсия музыки с ZX Spectrum, так что сейчас я просто взял инструменты из тех старых модулей и сделал на их базе музыку для шкатулки.

В результате работы конвертора создается текстовый файл в формате ассемблера PIC. Его содержимое нужно скопировать в конец исходника прошивки и скомпилировать. В результате получится прошивка в виде hex-файла с нужной музыкой.

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

Если среди читателей найдутся желающие и способные создавать красивую чип-музыку для шкатулок и тому подобных музыкальных поделок на микроконтроллерах — буду рад сотрудничеству.

Исходники

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

Источник: http://www.pvsm.ru/news/55150

Ссылка на основную публикацию
Adblock
detector
",css:{backgroundColor:"#000",opacity:.6}},container:{block:void 0,tpl:"
"},wrap:void 0,body:void 0,errors:{tpl:"
",autoclose_delay:2e3,ajax_unsuccessful_load:"Error"},openEffect:{type:"fade",speed:400},closeEffect:{type:"fade",speed:400},beforeOpen:n.noop,afterOpen:n.noop,beforeClose:n.noop,afterClose:n.noop,afterLoading:n.noop,afterLoadingOnShow:n.noop,errorLoading:n.noop},o=0,p=n([]),h={isEventOut:function(a,b){var c=!0;return n(a).each(function(){n(b.target).get(0)==n(this).get(0)&&(c=!1),0==n(b.target).closest("HTML",n(this).get(0)).length&&(c=!1)}),c}},q={getParentEl:function(a){var b=n(a);return b.data("arcticmodal")?b:(b=n(a).closest(".arcticmodal-container").data("arcticmodalParentEl"),!!b&&b)},transition:function(a,b,c,d){switch(d=null==d?n.noop:d,c.type){case"fade":"show"==b?a.fadeIn(c.speed,d):a.fadeOut(c.speed,d);break;case"none":"show"==b?a.show():a.hide(),d();}},prepare_body:function(a,b){n(".arcticmodal-close",a.body).unbind("click.arcticmodal").bind("click.arcticmodal",function(){return b.arcticmodal("close"),!1})},init_el:function(d,a){var b=d.data("arcticmodal");if(!b){if(b=a,o++,b.modalID=o,b.overlay.block=n(b.overlay.tpl),b.overlay.block.css(b.overlay.css),b.container.block=n(b.container.tpl),b.body=n(".arcticmodal-container_i2",b.container.block),a.clone?b.body.html(d.clone(!0)):(d.before("
"),b.body.html(d)),q.prepare_body(b,d),b.closeOnOverlayClick&&b.overlay.block.add(b.container.block).click(function(a){h.isEventOut(n(">*",b.body),a)&&d.arcticmodal("close")}),b.container.block.data("arcticmodalParentEl",d),d.data("arcticmodal",b),p=n.merge(p,d),n.proxy(e.show,d)(),"html"==b.type)return d;if(null!=b.ajax.beforeSend){var c=b.ajax.beforeSend;delete b.ajax.beforeSend}if(null!=b.ajax.success){var f=b.ajax.success;delete b.ajax.success}if(null!=b.ajax.error){var g=b.ajax.error;delete b.ajax.error}var j=n.extend(!0,{url:b.url,beforeSend:function(){null==c?b.body.html("
"):c(b,d)},success:function(c){d.trigger("afterLoading"),b.afterLoading(b,d,c),null==f?b.body.html(c):f(b,d,c),q.prepare_body(b,d),d.trigger("afterLoadingOnShow"),b.afterLoadingOnShow(b,d,c)},error:function(){d.trigger("errorLoading"),b.errorLoading(b,d),null==g?(b.body.html(b.errors.tpl),n(".arcticmodal-error",b.body).html(b.errors.ajax_unsuccessful_load),n(".arcticmodal-close",b.body).click(function(){return d.arcticmodal("close"),!1}),b.errors.autoclose_delay&&setTimeout(function(){d.arcticmodal("close")},b.errors.autoclose_delay)):g(b,d)}},b.ajax);b.ajax_request=n.ajax(j),d.data("arcticmodal",b)}},init:function(b){if(b=n.extend(!0,{},a,b),!n.isFunction(this))return this.each(function(){q.init_el(n(this),n.extend(!0,{},b))});if(null==b)return void n.error("jquery.arcticmodal: Uncorrect parameters");if(""==b.type)return void n.error("jquery.arcticmodal: Don't set parameter \"type\"");switch(b.type){case"html":if(""==b.content)return void n.error("jquery.arcticmodal: Don't set parameter \"content\"");var e=b.content;return b.content="",q.init_el(n(e),b);case"ajax":return""==b.url?void n.error("jquery.arcticmodal: Don't set parameter \"url\""):q.init_el(n("
"),b);}}},e={show:function(){var a=q.getParentEl(this);if(!1===a)return void n.error("jquery.arcticmodal: Uncorrect call");var b=a.data("arcticmodal");if(b.overlay.block.hide(),b.container.block.hide(),n("BODY").append(b.overlay.block),n("BODY").append(b.container.block),b.beforeOpen(b,a),a.trigger("beforeOpen"),"hidden"!=b.wrap.css("overflow")){b.wrap.data("arcticmodalOverflow",b.wrap.css("overflow"));var c=b.wrap.outerWidth(!0);b.wrap.css("overflow","hidden");var d=b.wrap.outerWidth(!0);d!=c&&b.wrap.css("marginRight",d-c+"px")}return p.not(a).each(function(){var a=n(this).data("arcticmodal");a.overlay.block.hide()}),q.transition(b.overlay.block,"show",1*")),b.overlay.block.remove(),b.container.block.remove(),a.data("arcticmodal",null),n(".arcticmodal-container").length||(b.wrap.data("arcticmodalOverflow")&&b.wrap.css("overflow",b.wrap.data("arcticmodalOverflow")),b.wrap.css("marginRight",0))}),"ajax"==b.type&&b.ajax_request.abort(),p=p.not(a))})},setDefault:function(b){n.extend(!0,a,b)}};n(function(){a.wrap=n(document.all&&!document.querySelector?"html":"body")}),n(document).bind("keyup.arcticmodal",function(d){var a=p.last();if(a.length){var b=a.data("arcticmodal");b.closeOnEsc&&27===d.keyCode&&a.arcticmodal("close")}}),n.arcticmodal=n.fn.arcticmodal=function(a){return e[a]?e[a].apply(this,Array.prototype.slice.call(arguments,1)):"object"!=typeof a&&a?void n.error("jquery.arcticmodal: Method "+a+" does not exist"):q.init.apply(this,arguments)}}(jQuery)}var debugMode="undefined"!=typeof debugFlatPM&&debugFlatPM,duplicateMode="undefined"!=typeof duplicateFlatPM&&duplicateFlatPM,countMode="undefined"!=typeof countFlatPM&&countFlatPM;document["wri"+"te"]=function(a){let b=document.createElement("div");jQuery(document.currentScript).after(b),flatPM_setHTML(b,a),jQuery(b).contents().unwrap()};function flatPM_sticky(c,d,e=0){function f(){if(null==a){let b=getComputedStyle(g,""),c="";for(let a=0;a=b.top-h?b.top-h{const d=c.split("=");return d[0]===a?decodeURIComponent(d[1]):b},""),c=""==b?void 0:b;return c}function flatPM_testCookie(){let a="test_56445";try{return localStorage.setItem(a,a),localStorage.removeItem(a),!0}catch(a){return!1}}function flatPM_grep(a,b,c){return jQuery.grep(a,(a,d)=>c?d==b:0==(d+1)%b)}function flatPM_random(a,b){return Math.floor(Math.random()*(b-a+1))+a}