Аналог Аналогового синтезатора

andriano
andriano аватар
Offline
Зарегистрирован: 20.06.2015

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

Итак, планируется создание музыкального синтезатора. Рассматривается именно музыкальный инструмент, а не нечто свистяще-булькающее для генерации шумовых эффектов.
Большая часть как этапов синтеза, так и используемых "устройств" - аппаратная. Причины - две:
- чисто программный синтез звука явно превосходит возможности AVR,
- у меня есть некоторый опыт по созданию аналоговых синтезаторов (опыт 20-летней давности).

Сначала немного теории.

Ухо человека все воспринимает в логарифмической шкале, как частоту звука, так и амплитуду. (Собственно, для человека вообще характерно логарифмическое восприятие, которое напрочь отбивают в начальных классах школы, пытаясь приучить к линейной шкале)
Амплитуду принято измерять в дБ, а частоту в октавах (изменение частоты вдвое) и производных от нее единицах.
В настоящее время в европейской музыке общепринят равномерно темперированный строй (хроматическая гамма), в котором 12 нот логарифмически равномерно расположениы в пределах октавы. Интервал между двумя соседними нотами (т.е. 1/12 часть октавы) называется полутон. Для более точной характеристики высоты звука полутон делится еще на 100 центов. Предел различающей способности уха в области наилучшей слышимости для большинства людей лежит в диапазоне от 6 до 40 центов. Для людей с хорошим музыкальным слухом он составляет 3-4 цента.
Музыкальный дианазон простирается от 16.35 Гц (До Субконроктавы) до 4186 Гц (До Пятой октавы) (кстати, в отечественной и европейской музыке нумерация октав несколько различается). Звуки выше этого диапазона в качестве нот не используются, но заняты обертонами т.е. высшими гармоническими составляющими музыкальных звуков. В терминологии: 1-я гармоника - основной тон, 2-я гармоника - 1-й обертон, 3-я гармоника - 2-й обертон и т.д. Обертона - важная составляющая часть звука, в значительной степени определяющая его тембр.
Динамический диапазон (отношение сигнал/помеха) желательно обеспечить 60-80 дБ, т.е. максимальный сигнал помехи (напряжение, звуковое давление) должен быть менее 1/1000 полезного сигнала. Для сравнения 8-разрядный звук обладает отношением сигнал/шум около 50 дБ.

Синтезаторы принято делить на одноголосые и многоголосые/полифонические. Это совершенно различные инструменты: первые являются функциональным аналогом духовых или смычковых инструментов, а вторые - инструментов, предназначенных для игры аккордами.

Обычно классический синтезатор состоит из следующих частей:
- некоторого количества генераторов тона (обычно не менее двух даже в одноголосых инструментах, или по одному-два на голос - в многоголосных),
- управляемого фильтра (по числу голосов или тонгенераторов, возможно, отдельный на генератор шума),
- управляемого усилителя (один на голос + 1 для генератора шума, возможно, + 1 общий),
- одного или нескольких (обычно 1-2 на голос) формирователя огибающей звука - ADSR (от сокращений Attac, Decay, Sustain, Release),
- от одного до четырех низкочастотных генераторов, предназначенных для модуляции генератора тона, фильтра, усилителя,
- генератора шума (факультативно),
- также факультативно - задержек, формантных фильтров, генераторов сигнала произвольной формы и пр.

Это что касается классического синтезатора. В последнее время приобрел широкое распространение таблично-волновой синтез. В общих чертах - это оцифрованный звук реальных музыкальных инструментов. Но, учитывая, что (если исходить из стандарта MIDI) имеется 128 нот, каждая со 128 уровнями громкости и совершенно невообразимым разнообразием длительностей, да еще и стандартных инструментов никак не меньше 128, то все оцифровки должны требовать чудовищного объема памяти. Поэтому звук режут на кусочки, интерполируют, масштабируют, а потом склеивают между собой.

Теперь переходим конкретике.

Данный проект предусматривает создание MIDI синтезатора, совмещающего классический синтез характерный для аналоговых синтезаторов, с таблично волновым синтезом в различных режимах работы. Режимы примерно такие:
- 1-но, 2-х, 3-х, 4-х, 6-ти, 7-ми, 8-ми, 9-ти, 10-ти или 12-голосного классического синтезатора,
- полифонического таблично-волнового синтезатора,
- синтезатора, где в одном канале работает классический синтез, а в другом - таблично-волновой,
- синтезатора, где в пределах одного канала ниже определенной ноты работает таблично-волновой синтез, а выше - классический (соло и аккомпанемент),
- синтезатора, где в пределах одного канала выше определенной ноты работает таблично-волновой синтез, а ниже - классический (бас и аккорды).

Теперь по блокам.

Генератор тона.
Обычно в одноголосых синтезаторах их не менее двух - для создания эффекта унисона. В сочетании с вибрато (а спектр сигнала с амплитудным вибрато в точности соответствует спектру двух генераторов в унисон с небольшой расстройкой. Частотного вибрато - чуть сложнее, но также состоящему из нескольких близких частот) достигается эффект имитации множества звучащих одновременно голосов. В принципе, второй генератор может использоваться для игры в октаву, в квинту или терцию (а для больших любителей - в секунду).
С точки зрения цифровой техники генератор целесообразно делать на делителях частоты. 8-разрядный делитель не обеспечивает необходимой точности строя даже в пределах одной октавы. А 16-разрядный делитель частоты от 1-МГц генератора как раз хорошо ложится на весь музыкальный диапазон с допустимой погрешностью.
В классическом синтезаторе обычно есть выбор из нескольких форм волны. Наиболее полный набор: синус, пила, треугольник, меандр, прямоугольник с управляемой скважностью. Сокращенный обычно: пила, меандр. Я в своем проекте выбрал: прямоугольник с регулируемой скважностью (меандр как частный случай).
На роль генератора тона может претендовать как встроенный 16-разрядный таймер AVR, так и отдельный делитель, например, на 2/3 от микросхемы таймера 8253 (один канал для нужной частоты, другой - для задания длительности импульса, обеспечивающего нужную скважность).
Минус встроенного таймера - их слишком мало. Минус 8253 - нуждается во внешнем генераторе и параллельной шине данных.
Коэффициенты деления просчитываются заранее на ПК и содержатся в виде массивов в PROGMEM с интервалом в 3 цента (32 значения на полутон). В дальнейшем используются только коэффициенты из таблицы, промежуточные значения не интерполируются (за ненадобностью). Рассчитывается только коэффициент, отвечающий за скважность.
На генерируемую частоту должны оказывать влияние:
- номер ноты,
- питч-бэнд,
- один или несколько низкочастотных генераторов,
- генератор огибающей.

Управляемый фильтр.
По сути - классический универсальный фильтр на двух интеграторах и двух инверторах. Имеет выходы: ФНЧ, ФВЧ, ПФ и РФ (последнее - не Российская Федерация, а Режекторный Фильтр). В наиболее навороченных синтезаторах используются все. Мой опыт (и не только мой) говорит, что если не гнаться за шумовыми эффектами, а ограничиться музыкальным звуком, достаточно только ФНЧ. Но это уже вопрос исключительно коммутации и дополнительных ручек управления.
Варианты реализации:
1. Активные элементы:
1.а. ОУ,
1.б. Специализированная микросхема фильтра с уже подобранными конденсаторами интеграторов (например, UAF42),
1.в. Программно перестраиваемый фильтр (например, MAX260-MAX268).
2. Пассивные элементы:
2.а. Цифровые потенциометры (AD5204-06, AD5241-42, AD8400-02-03, CAT5116, MAX6160-61, MCP41xxx-42xxx, x9c102-103-104...).
2.б. Цифровые регуляторы громкости (FM62429, LC75410, M61539, M62420-21-29, NGW1199, PT2257-58).
2.в. Перемножающие ЦАП (572ПА1, AD7520-21).
В принципе, наиболее привлекательным решением могли бы служить 1.в., вообще не требующий 2. Но диапазон перестройки, как правило, ограничен одной октавой, а в широких пределах может регулироваться частотой от внешнего генератора. Вот этот вот генератор - по одному на каждый фильтр - представляется тяжеловатым решением.
У фильтра регулируются:
- частота (называется cutoff),
- добротность (называется resonance),
- значения частоты в каждой из точек ADSR,
- глубина влияния следующих факторов на частоту (и, возможно, добротность):
-- вибрато от одного или нескольких низкочастотных генераторов,
-- ADSR, причем, влияние может быть как со знаком "+" так и "-".

Управляемый усилитель.
Аппаратный - цифровой регулятор громкости. (например, M62429)

Генератор ADSR.
Планируются программные. По 1-2 на голос (либо общий, либо раздельные для усилителя и фильтра) Реализуются в прерывании по таймеру.

Низкочастотные генераторы.
Также программные: планируется 2 или 4. Если 4, то 2 из них с внешней синхронизацией, а 2 - с синхронизацией от сигнала NOTE_ON. Если 2 - то переключаемые.

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

Таблично-волновой синтезатор.
Планируется использование VS1053. Возможно, старую ISA плату Creative AWE32.

Управление.
Общее управление Arduino Mega 2560. В наиболее компактном варианте одноголосого синтезатора ею все и ограничится: из имеющихся 4 таймеров 2 будут использованы для тонгенераторов, а 2 оставшиеся - для задания частоты программируемым фильтрам.
В более общем случае будут использованы фильтры на интеграторах и 4 тонгенератора, которые будут в зависимости от режима работать либо как одноголосый, либо как двухголосый, либо как 4-голосый инструмент.
Возможно дополнительно подключение дополнительных голосов, формируемых либо Arduino Pro Mini, либо таймером 8253. Ну, либо той же Мегой 2560, если голосов потребуется много.

Да, в проекте используются системные файлы, измененные в соотетствии с http://arduino.ru/forum/programmirovanie/etyudy-dlya-nachinayushchikh-me...

____________________________

Сразу выражаю благодарность всем, кто словом или советом принял участие впроекте. В первую очередь dimax, ЕвгениийП, Arhat109-2.
 

andriano
andriano аватар
Offline
Зарегистрирован: 20.06.2015

Пока проект разворачивается на Arduino Uno, а в нем есть только один 16-разрядный таймер.
Но даже для одноголосого инструмента одного тонгенератора мало, нужно минимум два.
Была предпринята попытка сделать программно-аппаратный делитель частоты с использованием свободного 8-разрядного таймера 2.
Идея состояла в том, чтобы для каждой ноты подобрать такой делитель частоты, который обеспечивал бы необходимую точность строя и при этом мог быть представлен произведением двух чисел, одно из которых меньше 256. Точнее, трех чисел, учитывая коэффициент предделения.
Тогда прерывание по таймеру мы настраиваем как раз по этому делителю (тому, что меньше 256), а в прерывании делаем приращение переменной-счетчика. По достижении счетчиком определенного значения нужный пин перекидывается в нужное состояние.
Такая идея была реализована, но продемонстрировала 2 существенных недостатка:

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

2. Прерывания от таймера 2 иногда задерживаются другими прерываниями, например, от таймера 0 или от последовательного порта (MIDI-ноты откуда-то брать нужно!). Это приводит к посторонним призвукам. Первые эксперименты я делал, используя пластмассовые компьютерные колонки. Учитывая, что колонки я еще и включал как можно тише, призвуков не заметил. Но стоило надеть наушники - они и появились тут как тут. В общем, второй таймер можно, конечно, использовать в процессе отладки, но из финального варианта его однозначно придется исключить. Правда, его, вероятно, можно было бы использовать не для тонгенератора, а в случае использования программируемого фильтра. Там его погрешности вполне приемлемы: достаточно вообще генерации октавного сигнала, восполняя промежуток в коэффициентах предделения. Обидно, правда, использовать только половинку от микросхемы цифрового фильтра, которая в несколько раз дороже Pro Mini.

Листинг - ниже.
Предупреждаю сразу - обработка MIDI-сообщений еще не написана, "раздача" голосов по генераторам -тоже. Поэтому пока можно только тестировать, нажимая и отпуская по одной ноте. Если нажать новую ноту прежде, чем отпустить старую, звук, скорее всего, пропадет. По крайней мере, в канале таймера 2. Чтобы он появилсявновь, следующую ноту нужно взять, отступив октавы на 3 от того места, где нота заткнулась.
Подключение пинов описано в листинге. Сигнал с MIDI, естественно, идет через оптопару.

Скетч:

Файл Arhat_digOut.c

Файл FreqNote1.c

Файл FreqNote2.c

 

Arhat109-2
Offline
Зарегистрирован: 24.09.2015

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

И если взять за эталон не есстественную ноту, а скажем какую-то сверхвысокую или сверхнизкую частоту (надо смотреть что удобнее растягивать или сжимать далее), то ваши коэффициенты деления вырождаются как раз в такие таблицы "сколько держать этот уровень" по времени на выходе ШИМ. В этом случае у вас может получиться 1 вывод ШИМ (16бит) = 1 голос.

То есть, выбираете частоту дискретизации семплов много выше 20кгц .. скажем 128кгц. Это частота вашего ШИМ сигнала. Вот из неё потом, внешней схемой и формируется на ЦАП реальный голос, который подаете на суммирующий аналоговый усилитель с регулировками громкости полифонии. А все остальное "внутри" дуньки (дунек) имеем:

1. Образцы семплов (флеш) на эталонной ноте, скажем в 20кгц. (раз в 5 больше макс.) с частотой дискретизации в 120-200кгц. (раз в 10 больше 1 периода эталонной ноты семпла, лучше не менее 20) с длительностью оцифровки в 100 периодов .. это оценочно потребует 20*100 = 2000 байт на семпл.

2. Таблицы, содержащие длительности ШИМ (доля 1 от периода ШИМ и кол-во периодов повторения этого меандра) при его фикс. частоте в те самые 120-200кГц для каждой ноты и текущей громкости семпла. Их много в соответствии с требуемой нотой, вибрато, стаккато и пр. музыкальных "предикатов" (давно это было, уже не помню нифига, но я когда-то шел этим путем на КР580ИК80А .. помню только что таблицы готовились под какие-то наши "сверхбольшие" на то время флеш микросхемы и в несколько штук .. всё тогда оказалось слишком дорого и до конечного результата не дошло .. работы с Киевской консерваторией .. 198.. какой-то год)

Алгоритм в этом случае крайне прост: 16-битным таймером выдаем ШИМ на заданной ноге согласно требуемому значению на фикс. частоте в 120-200кгц. Входной поток - ноты и "модификаторы" и он достаточно редок, что есть благо. У меня укладывалось в байтовый поток, какой-там формат у МИДИ не смотрел. Согласно входной ноте (это индекс в большом массиве пересчетных коэффициентов, а стало быть выборка шустра) и текущей позиции семпла - вытаскиваем "как долго петь этот ШИМ и какой он" - это 2 числа. Одно запихивается в регистр OCR таймера и формирует сам ШИМ, а второе пихается во второй таймер (и наверное можно 8 бит), который формирует прерывание "пора сменить ШИМ". Всё можно уложить в несколько простых команд и для 16Мгц проблем возникать не должно...

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

.. не знаю, может как-то сумбурно изложил, а может Вы этот же подход и имели ввиду. Плохо уже помню ту работу.

andriano
andriano аватар
Offline
Зарегистрирован: 20.06.2015

Arhat109-2, то, о чем Вы писали вначале, называется таблично-волновым синтезом. Только Ваше мнение, что "флеша в Меге как грязи", мягко говоря, не согласуется с реальным состоянем дел.

Проблема в том, что оцифровать для инструмента единственную ноту - это вообще ни о чем. Для посредственной имитации музыкального инструмента нужно 2-3 ноты на октаву, для хорошей - с шагом не более 2-3 нот, а лучше - каждую ноту. Т.е. от 20 до 100 нот.

Но это еще не все.

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

Вы, наверное, в общих чертах в курсе, как работает алгиритм сжатия MPEG Layer 3 (MP3). Там перед сжатием из звука выбрасывается то, что человек либо совсем не услышит, либо почти не заметит. Для того, чтобы разработать такой алгоритм, нужно было выполнить достаточно фундаментальную НИР, исследующую физиологию и психологию человеческого слуха, провести кучу экспериментов с привлечением как эксперов, так и групп "средних" слушателей...

Примерно такая же работа была проведена и для того, чтобы добиться узнаваемого звука инструментов при вменяемом объеме данных. Скажу так: хорошо сжатый банк данных посредственного качества для набора инструментов General MIDI весит полмегабайта. А хорошая оцифровка единственного рояля - 12 Мбайт. По сравнению с этим объемом памяти Меги как-то выглядит не очень внушительно.

В любом случае, таблично-волновой синтез - лишь ОДИН ИЗ нескольких различных способов синтеза. У него есть свои достоинства и существенные недостатки. И на данном этапе этот вид синтеза меня не интересует. В первую очередь по причине "тяжеловесности" как с точки зрения объемов требуемой памяти, так и объемов подготовительной работы для формирования банков звуков.

 

Но давайте, все-таки, перейдем к Вашим идеям о конкретной реализации, которых я, честно говоря, не понял.

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

Второго абзаца не понял совсем. Ни каждого предложения в отдельности ни всего вместе.

Дальше - третий абзац. Ладно, записали некоторый звук на частоте дискретизации 128 кГц. Какая нужна внешняя схема? Как при помощи АЦП формировать реальный голос? И зачем вообще АЦП, если у нас ШИМ? Или зачем ШИМ, если есть АЦП? При наличии ШИМа АЦП не нужен - все решается интегратором.

4-й абзац. Оцифровка на частоте в 10-20 раз больше частоты ноиы совершенно неприемлема. Аместо "родных" обертонов получим всякую "грязь". О формантных областях я уже даже не говорю. В общем, любую ноиу оцифровывать можно только на той частоте, которая не менее чем в два раза (по теореме Котельникова-Шеннона) превосходит частоту высшей гармоники. А как показывает практика, даже у самых низких нот гармоники доходят минимум до 6-8 кГц. Т.е. нота, скажем, 16 Гц, а частота оцифровки должна быть не менее 16 кГц. Уложимся мы в 2 кбайта? Нет, если бы сигнал был строго периодический и неизменный во времени - уложились бы. Но - увы, ни тем, ни другим свойством музыкальный звук не обладает. И ухо это прекрасно слышит. Т.е. легко распознает подделку.

5-й абзац и дальше. Флэш-память изобретена только а 1984 г., так что сомневаюсь, что в 1980-х Вы уже могли ее где-то использовать. Если я Вас правильно понял, Вы предлагаете перепрограммировать генератор ШИМ примерно так с частотой дискретизации. Правда, не поннял, под частотой дискретизации подразумевается порядок 44100-48000 либо указанная Вами повышенная 120000-200000.

6-й абзац. MIDI никакого отношения к звуку не имеет. Совсем. Это некоторый аналог нотной записи. Ни частоты, ни спектра в MIDI записи нет.

В общем, ничего не понял.

Поэтому не могу сказать, есть ли в Вашей идее рациональное зерно или нет.

Давайте попробуем чуть конкретнее.

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

Первое - что именно из этих двух нот мы будем сохранять в банке?

Второе - как из того, что есть в банке, воссоздать записанную ноту?

Третье - как синтезировать ноту, отличающуюся от тех, запись которых была использована при составлении банка?

Arhat109-2
Offline
Зарегистрирован: 24.09.2015

Так, похоже что "объяснятель" из меня никакой, согласен. :)

Давайте по порядку. При оцифровке живого звука происходит банальщина: АЦП фиксит значения в 8-10-12-16 разрядов с частотой оцифровки, которая (согласно теореме..) принята в 44кгц. То есть, поток данных, пусть будет даже в 2 байта идет со скоростью "чиселко в 24микросекунды". Так ведь? :)

Далее. Соответственно, каким бы сложным не было звучание (одна нота одного инструмента, аккордная игра или вовсе полифония с вокалом), ничего в данном потоке .. не изменяется, как было 2 байта каждый 24мксек, так и осталось. Верно жеж? :)

То что Вы хотите реализовать есть некий вариант обратной задачи. Соответственно, если у вас есть "семпл" по 2 байта на цифру, и его не требуется корежить, то вполне достаточно выбрасывать эти 2 байта в 2 порта меги каждые 24мксек, чтобы потом подхватить их обратным параллельным ЦАП и воспроизвести оригинал. В этом случае, при 16Мгц и 6 тактах "на выброс пары байт в порт" (out, out, count--?, jump) , будет иметь 394 такта простоя и загрузка МК составит 6/400 = 1,5% что очень даже незаметно. Так ведь?

Вся проблема в этом подходе как раз те самые "гектары семплов", о которых Вы и пишете, ибо надо иметь по 1 семплу на все возможные варианты звычания во всем диапазоне часто, громкостей, длительностей и соло/аккордов .. даже на 1 инструмент никакой памяти "не хватит" при дотошном подходе, ибо звучание живого инструмента нелинейно по "всем параметрам". Даже при разных громкостях даже от банальной гитары можно получить ну очень разный звук, особливо когда усиление громкости начинает бить струной о корпус гитары.. так жеж? :)

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

Отсюдова, требуется сформулировать некие "упрощения".

С другой стороны, известно что ухо не слышит далее 16-18кгц (многие не слышат уже 14, сам проверял, когда-то и себя: слышал макс. 16400) и принято что порог слышимости составляет 20кгц. Что и определило принятый стандарт оцифровки в 44кгц. Этот факт также определяет верхний порог нотного стана в примерно 5кгц, ибо после него "тембр" становится единообразным для любого инструмента (неразличимым из-за малого количества различаемых гармоник). То, что выше - это уже разного рода "тарелочные шумы" ..

Там есть одна "засада", с которой я сталкивался в бытность решения похожей задачи: как ни странно, но есстественность воспроизведения определяется не столько чистотой воспроизведения тембра или отсутствием шумов, сколько высокой переходной характеристикой канала воспроизведения. При оцифровке в 44кгц имеем достаточно низкую переходную характеристику по скорости нарастания фронта .. достаточно качественно у меня получилось при изготовлении усилительного тракта для кассетного магнитофона (были такие) в режиме прямолинейной АЧХ вплоть до 200кгц при отключенной цепи ООС и отсутствии фильтров коррекции АЧХ магнитной головки. Вот при такой переходной характеристике, да при 30дБ ООС и КНИ в 1% я получал есстественность воспроизведения с магнитной ленты такую, что музыканты из нашей консервы были не в состоянии отличить игру на гитаре от магнитофона, находясь в соседней комнате (50 на 50 из 20 попыток). При этом АЧХ была всего лишь 40гц .. 16.5кгц, а с ленты, прошедшей тракт хотя бы дважды падала до 12.5кГц, однако. Вот поэтому я предложил Вам взять частоту оцифровки в диапазоне 120-200кгц.

Отсюда и была моя идея выше: если взять частоту генерации импульсов ШИМ в 100-200кгц, то её можно "не изменять", а управлять только скважностью этого ШИМ формируя конкретное звучание. Раз уж Вы запали на таймеры (можно пользовать параллельный ЦАП и работать целым портом или даже двумя, что мне кажется значительно проще и что я и делал на ИК80А).

То есть настраиваем выход OCR1C таймера 1 на вывод ШИМ с частотой скажем 200кГц. и управляем только его скважностью. В этом случае, для воспроизведения "импульса" в 20кгц нам потребуется 10 "тактов" этого выхода. Второй таймер OCR0A и настраиваем на вывод пачки в количестве этой самой 10-ки. Ширина импульсов будет определяться требуемой громкостью звучания этой частоты в 20кгц. В целом воспроизваедение всего сэмпла представит из себя последовательную перезагрузку регистров OCR1C и OCR0A в прерываниях по OCR0A, где 1-й таймер будет имитировать текущий уровень сигнала, а нулевой длительность текущего уровня.

Далее, я Вам предложил обойтись одним "эталонным" сэмплом на инструмент. Несмотря на нелинейность звучаний, тем не менее такое ограничение вполне оправдано в достаточно широком диапазоне параметров. Да, семпл может быть "длинным", ибо тембр часто сильно меняется со спадом громкости. Тут надо опять же пойти на какие-то упрощения .. по моей практике, вполне достаточно было иметь семпл длинной в 0.25сек от фронта, чтобы его потом масштабировать куда следует. Это при 25мксек оцифровки дает объем в 10к слов (20кбайт - 2 таймера!) на семпл. Для сохранения богатства тембра можно оцифровывать нижний диапазон звучания .. на верхнем диапазоне ваши "обертона" все равно никто не услышит.

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

dimax
dimax аватар
Offline
Зарегистрирован: 25.12.2013

Arhat109-2, той скважности на 200кГц будет то всего.. с гулькин нос.. 16000/200 = 80 шагов.

Arhat109-2
Offline
Зарегистрирован: 24.09.2015

Ну вот по здравому размышлению, я тоже не вижу пользы от использования таймеров МК для генерации выходного сигнала. Уж проще гнать уровень сигнала в порт и преобразовывать его параллельным ЦАП в уровень "на лету". В свое время sc.exe вполне справлялся с 4-х голосым синтезом даже на x286 на 16Мгц. "таблично-волновым" способом даже при выводе на внутренний динамик компа (сам когда-то им баловался).

Logik
Offline
Зарегистрирован: 05.08.2014

А в результате то что хочется? Если простую пищалку уровня пианино для трехлеток - слишком глубоко копнули. Если хочется чтоб хот ть местами звучало как настоящий инструмент - не тот процессор, причем сильно совершенно не тот, его не хватает по всем возможным параметрам. Не хватит ни для банка нот, ни для пересчета нот даже по громкости. Вывод музыкального тона через ШИМ - канонический геморой, эталон маразма начинающих (пищалка на ПК и вывод музыки через неё - была такая хроника в 90-х, слава богу не у меня )))) Зачем в это лезть сейчас? Здесь хороше DSP и ЦАП, но даже при нормальном железе все потребует очень нехилого искуства программирования, в сочитании с неясностью результата.

А если так невмоготу шимом музыку играть, то и храните представление ноты в самом удобном виде, как набор необходимых длительностей 0 и 1 на пине, формируйте его потом таймером на выход сразу. Высоту перещитать легко будет, изменение громкости наверно возможно, полифонию сделать - ну в принципе может и можно попробовать.

andriano
andriano аватар
Offline
Зарегистрирован: 20.06.2015

Arhat109-2, в первых трех абзацах Вы по сути рассказываете, как работает "магнитофон". Хочу только заметить, что вряд ли имеет смысл отправлять в порт константу, записанную в паре регистров, поэтому данные о звуке надо еще откуда-то читать. Итого в 6 тактов не укладываемся - это раз. Но самое главное - любое прерывание прервет поток данных и разрушит нашу идиллию. В PC для решения этой проблемы использовался DMAC, есть ли что-то подобное в AVR, не знаю.

Когда-то я слышал 19000. Недавно обнаружил, что "осталось" только 13000. Хотя жена до сих пор слышит 18000 (а может, и выше - не проверял, было только 18000).

200кГц на кассетном магнитофоне? Не верю!
Ширина магнитного зазора 1.5 микрон, скорость протяжки 4.76 см/с. Посчитайте, даже если минимальную длину волны мы примем равной двум ширинам зазора (рекомендуется 3-5), частот выше 16 кГц мы не получим. Геометрию не обманешь!
Кстати, головка имеет частотную характеристику со спадом НЧ 6 дБ на октаву, так что ни о какой линейной АЧХ тракта и речт быть не может. Или мы опять говорим о разных вещах?

Абзацы 8-9: Правильно ли я понимаю, что Вы предлагаете использовать ШИМ вместо ЦАП?

Абзац 10: Я не понимаю, что такое "импульс 20 кГц". В моем представлении импульс - это единичное изменение напряжения (звукового давления), имеющее широкий спектр, но не имеющее периода (а килогерцы бывают только у периодического сигнала). Соответственно, не понял и всех последующих рассуждений.
Отдельно последнее предлжение: т.е. 1-й иаймер по сути обеспечивает ШИМ низкочастотного сигнала, а по нулевому таймеру его перепрограммируем с постоянной частотой, скажем, 44100 раз в секунду?

Предпоследний абзац: не могу согласиться с достаточностью 1 сэмпла на инструмент. У музыкального инструмента, как правило, есть формантные области. Т.е. если мы посмотрим спектрограмму, то обнаружим пики на одних и тех же частотах вне зависимости от высоты ноты. А при единственном сэмпле пики будут сдвигаться пропорционально частоте. Можно, коначно, попытаться построить "эквивалениную схему" музыкального инструмента и с ее помощью срезать форманты, после чего записать сэмпл. При воспроизведении сэмпл сначала масштаируется, а после этого на него накладывается формантный фильтр. Звук будет намного естественнее, но такой способ подразумевает применение сложного фильтра при воспроизведении (десятки умножений и сложений), с чем AVR по моему мнению уже не справится - нужен DSP.
Но и это еще не все. Например, в гитаре или ф-но звучит струна. По мере звучания она излучает энергию, поэтому звук со временем затухает. Но т.к. энергия излучается неравномерно по спектру (те самые форманты!), и затухать эти формантные области будут быстнее. Ну напимер, формантная область 2.6 кГц. Для звука 440 Гц это 6-я гармоника, именно она и затухнет быстрее всего. Иеперь мы берем и переинтерполируем на 880 Гц. У нас опять быстрее зхатухает 6-я гармоника, что составляет 5.2 кГц, а нам надо, чтобы заиухала 3-я гармоника на тех самых 2.6 кГц. Отсюда, опять же, получаем неестественное звучание.

Последего абзаца опять не понял.

andriano
andriano аватар
Offline
Зарегистрирован: 20.06.2015

dimax пишет:

Arhat109-2, той скважности на 200кГц будет то всего.. с гулькин нос.. 16000/200 = 80 шагов.

Что соответствует динамическому диапазону 40 дБ.

andriano
andriano аватар
Offline
Зарегистрирован: 20.06.2015

Arhat109-2 пишет:

Ну вот по здравому размышлению, я тоже не вижу пользы от использования таймеров МК для генерации выходного сигнала. Уж проще гнать уровень сигнала в порт и преобразовывать его параллельным ЦАП в уровень "на лету". В свое время sc.exe вполне справлялся с 4-х голосым синтезом даже на x286 на 16Мгц. "таблично-волновым" способом даже при выводе на внутренний динамик компа (сам когда-то им баловался).

Если мы берем хоть мало-мальски приличный звук на PC, то это _только_ DMA.

Если мы говорим о PC-спикере, то ни о каком качестве говорить не приходися.

И самое главное: прежде, чем воспроизводить звук, его нужно синтезировать. Пока все Ваши рассуждения касались воспроизведенитя записанного звука, но не имели никакого отношения к собственно синтезу. А для прямого синтеза звука у AVR явно недостаточная мощность, нужен минимум DSP.

Поэтому я решил пойти другим путем: аппаратно встроенным таймером генерируется "заготовка" звука, после чего она обрабатывается аналоговыми цепями, имеющими цифровое управление. И если для воспроизведения качественного звука частота выдачи сигнала "на гора" должна составлять не менее 40 кГц при временных погрешностях менее 1 мкс, то для управляющего воздействия вполне допустим период более 1 мс с погрешностью того же порядка. Т.е. если мы при непосредственой выдаче звука задержим 25 мкс период на 10 мкс - это катастрофа. А если мы при 2 мс периоде управляющего воздействия задержим его на 1 мс, ничего страшного не случится.

Arhat109-2
Offline
Зарегистрирован: 24.09.2015

Так в холиварной теме про STM32 я и отписался что "гимны петь" нужен DMA и DAC .. специфика дунек - это задачи управления и реакции на внешние события, а не художественный свист и малевичи на экранах .. :)

andriano
andriano аватар
Offline
Зарегистрирован: 20.06.2015

Ну, выходит, мы одинаково оцениваем ситуацию.

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

Я думаю, производительности AVR вполне достаточно для того, чтобы принять MIDI-команду и периодически - раз в 1-2 миллисекунды - корректировать высоту тона, частоту фильтра, коэффициент усиления, и даже на полностью софтверный LFO.

Arhat109-2
Offline
Зарегистрирован: 24.09.2015

Должно быть "запросто". :)

ИМХО, мне кажется что и синтезировать звук она сможет .. но не при тех "упрощениях" к которым Вы стремитесь.

andriano
andriano аватар
Offline
Зарегистрирован: 20.06.2015

Что Вы подразумеваете под "упрощениями"?

Пока остаюсь при мнении, что если 328 даже сможет "синтезировать" звук (в чем лично я сомневаюсь), то она не способна вывести синтезированный звук наружу ввиду отсутствия DMA и DAC.

Arhat109-2
Offline
Зарегистрирован: 24.09.2015

Под "упрощениями" я понимаю ваше желание выдать качественный сигнал (точнее 1/32 тона, так жеж?) силами таймеров дуньки (ШИМ).

Я уже указал на вариант прямой выдачи уровня в порт (0..255) и дальнейшего получения сигнала силами параллельного ЦАП, да хоть бы и на базе R-2R делителей. пример R-2R ЦАП "на коленке". В этом случае, вы выбрасываете в порт уровень (1 команда МК!) и имеете динамический диапазон громкости около 46Дб (0..255). И мне кажется, что это допустимое упрощение ваших требований.

16Мгц в таком разе - вполне достаточно чтобы сгенерить 1 голос и без DMA. А может и даже пару-четверку. :)

andriano
andriano аватар
Offline
Зарегистрирован: 20.06.2015

1. "Таймеры дуньки" с этим справляются.

2. Динамический диапазон в 46 дБ категорически не устраивает.

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

Arhat109-2
Offline
Зарегистрирован: 24.09.2015

Ну вот и я про тоже самое, про "упрощения". :)

andriano
andriano аватар
Offline
Зарегистрирован: 20.06.2015

Видать, мы слово "упрощение" понимаем несколько по-разному.

andriano
andriano аватар
Offline
Зарегистрирован: 20.06.2015

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

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

Собственно, в порядке работы над проектом не только паяю/пишу программы, но и регулярно пытаюсь найти в И-нете какую-нибудь полезную для себя информацию. И на основании этого пришел к таким выводам:

1. Аналогов моего проекта мне в И-нете обнаружить не удалось.

2. Многочисленные проекты звуковых синтезаторов, имеющиеся в И-нете, можно разделить на следующие категории:

а) Синтезаторы звуковых эффектов. Собственно, только на звуковые эффекты и рассчитанные, звук музыкального качества генерить не способны.

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

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

г) Еще более примитивные околомузыкальные игрушки, которые, как правило, воспроизводят лишь сигнал прямоугольной формы без регулировки его громкости. Проектов таких очень много и самого разного назначения. Один из примеров описан мною на этом же форуме: http://arduino.ru/forum/proekty/floppy-hdd-music

 

Теперь по конкретному проекту:

Вариант а) для меня интереса не представляет.

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

Вариант г) - бывают забавные штуки. Как я уже писал, в этой категории я и сам поучаствовал. Думаю, на определенном этапе освоения Ардуино это было для меня полезно. И, возможно, не только для меня. По крайней мере, показ видео из этого проекта одному из моих коллег привел к идее постановки НИОКР военно-прикладного характера. Так что будем продвигать Ардуино в промышленных масштабах :).

Собственно, практически все решения, предлагаемые мне уважаемыми участниками форума, относятся к категории в). Думаю, это закономерно - зачем изобретать велосипед? Речь идет о таблично-волновом синтезе со следующими ограничениями:

1. Для всего диапазона звучания - единственная волновая форма.

2. Для всего динамического диапазона - единственная волновая форма.

3. Для всех фаз звучания - единственная волновая форма.

4. Предусматривается управление исключительно амплитудой сигнала. Никакой управляемой фильтрации звука не предусмотрено.

В результате звук получается ПЛАСТМАССОВЫМ, неестественным, пригодным в лучшем случае для музыкальной игрушки.

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

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

 

Очень упрощенная схема аналогового синтезатора: VCO -> VCF -> VCA -> Output

Где:

VCO - генератор управляемый напряжением,

VCF - управляемый напряжением фильтр,

VCA - управляемый напряжением усилитель.

Перерисуем схему с обозначением точек коммутации: VCO -(1)> VCF -(2)> VCA -(3)> Output

Так вот, все предложенные варианты исходят из того, что выходу Ардуино соответствует точка (3). А в своем проекте я назначаю для выхода Ардуино точку (1).

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

Именно такую схему я и задумал для реализации. Только в связи с тем, что цифровой таймер не способен генерить никакого сигнала кроме прямоугольного, набор волновых форм я свел к двум: меандр и прямоугольник со скважностью 7. Последнему есть вполне серьезные теоретические обоснования. Приводить тут их я не буду, скажу лишь, что в фориепиано молоточек ударяет по струне в точке, отстоящей от порожка на 1/7 длины струны, что приводит к такой же структуре спектра, как и в случае прямоугольника со скважностью 7. А ведь конструкторы рояля руководствовались не теоретическим выкладками, а ориентировались исключительно на собственный слух. Другими словами, имеет место совпадение теории и практики.

andriano
andriano аватар
Offline
Зарегистрирован: 20.06.2015

Собственно, дальнейший проект развивался уже исключительно на Mega 2560.

Постепенно определился с аппаратной частью.
Синтезатор, как и описывалось ранее, будет состоять из двух: мелодического и полифонического. Полифонический будет на микросхеме VS1053B, подключенной по аппаратному SPI на частоте 1 МГц (максимально допустимая частота ~1.6 МГц).
Мелодический синтезатор будет иметь два ражима: одноголосый и двухголосый. В них немного по-разному будет обрабатываться одновременное нажатие нот.
В синтезаторе будет:
- 2 генератора тона,
- 2 генератора амплитудной огибающей. Управление ими (величины Attac, Decay, Systain и Release) будет общими, а для запуска предусмотрен регулируемый сдвиг по времени. Т.к. предусмотрено их влияние не только на амплитуду, но и на частоту тона, для них будут дополнительные регуляторы отклонения частоты в 3-х точках (начало атаки, конец атаки, конец исчезновения).
- 3 LFO: 0-й имеет постоянную фазу, а 1 и 2 имеют фаза синхронизированную с началом атаки для каждого из голосов, генераторы можно переключать между 0 и 1 (для 1-го генератора) или 0 и 2 (для второго генератора), кроме того, можно переключать фазу (в фазе/в противофазе) между амплитудным и частотным вибрато,
- 2 управляемых фильтра - каждый для своего генератора тона. Частота и добротность фильтра могут управляться регуляторами на передней панели, генераторами огибающей (как своей, так и амплитудной), низкочастотными генераторами (двумя одновременно)
- 2 генератора огибающей для фильтров. Каждый для своего, начало синхронизируется с началом фазы атаки амплитудного генератора, но времена и отклонения настраиваются независимо. Кроме того, если амплитудная огибающая строится по 3-м точкам, то для фильтра - по 4-м.
- 2 управляемых усилителя. Управляются громкостью ноты, генератором огибающей и LFO.

В качестве генараторов тона используются 2 16-разрядных таймера Mega 2560. При этом можно выбрать одну из двух волновых форм: меандр и прямоугольник со скважностью около 7 (точнее для оптимизации по скорости 1/(1/8+1/64)). Коэффициент предделения таймера равен 8.
Фильтры используется на микросхеме MAX261. В качестве задающих генераторов используются два оставшиеся 16-разрядных таймера Меги, но уже с коэффициентом предделения 1. Частота фильтра равняется тактовой частоте, деленной на некоторый коэффициент, который можно задавать программно в диапазоне от 70 до 200. В области высоких частот из-за большой дискретности частот вследствие малых коэффициентов деления таймеров Меги для нужной точности настройки фильтра коэффициент деления фильтра приходится задавать, в области низких частот для требуемой точности достаточно менять лишь частоту тактирования фильтрв, а коэффициент деления фильтров - постояный равный максимальному значению 200.
Дискретность перестройки фильров 25 центов. Диапазон перестройки - от 40 Гц до 20 кГц.
Чтобы в области низких частот фильтра, когда управляющая частота опускается ниже границы звукового диапазона, не появлялось дополнительных призвуков, на входе и выходе фильтров предусмотрено дополнительное подключение низкочастотных фильтров 1-го порядка, настроенных на частоты среза 530 и 300 Гц. Подключение происходит, когда частоты фильтров опускаются ниже границ в 400 и 200 Гц соответственно. Первым подключается фильтр на входе, когда частота Найквиста попадает в звуковой диапазон, а вторым - на выходе, когда в звуковой диапазон попадает сама управляющая частота.
Для программирования фильтра нужно 7 контактов: 4 адреса, 2 данных и сигнал записи, поэтому было решено использовать для него целиком порт С Меги.
Первоначально планировалось использовать для этих целей порт L, там как раз свободно 7 контактов, а один занят выходным сигнало таймера, но потом из соображений разводки было решено перейти на порт С и пожертвовать одним неиспользуемым контактом. Листинг приводится как раз для порта L.

Принципиальная схема:

Выходы тонгенераторов (таймеров 1 и 3) - пины 5 и 11. Пины 3 и 4 - подключение дополнительных делителей напряжения, для чего пины переводятся либо в высокоимпедансное состояние, либо в режим выхода "LOW". По замыслу нужны для обеспечения одинаковой громкоасти для различной формы сигнала. Пины 2 и 7, а также 8 и 9 - подключение ФНЧ при низких частотах управляемого фильтра - фильтруют управляющую частоту фильтра при ее попадании в звуковой диапазон.
На B0505S собран отрицательный источник питания, обеспечивающий управляемый фильтр двухполярным питанием (+5В и -5В).

Первоначально планировалось, что на низких частотах (примерно до 800Гц) фильтр работает в режиме 1 с коэффициентом около 200, затем от 400 до 800 Гц коэффициент плавно меняется до 100. Начиная от 800 Гц фильтр переключается в режим 2, при этом сначала его коэффициент уманьшается примерно до 70, а затем остается вблизи этого значения вплоть да частоты фильтра 20 кГц и частоты задающего зенератора порядка 1.5 Мгц.
В дэйташите указано, что добротность фильтра вычисляется для режимов 1 и 2 по разным формулам. По идее добротность в режиме 2 должна быть выше при одном и том же управляющем коде, но на практике - как по осциллографу, так и на слух у меня получилось наоборот. Разбираться с этим было лень, и я решил ограничиться работой фильра исключительно в режиме 1, что потребовало увеличения максимальной управляющей частоты до 2 МГц. Но зато упростилось управление фильтрм: не нужно переключать режимы, не нужно запоминать добротность и пересчитывать и переключать ее при переключении режимов.

 

Когда более или менее определился с аппаратной составляющей, пересобрал макет на паечной макетке-шилде вместо беспаечной:

Кучка конденсаторов - это шунтирование аналоговых входов для уменьшения уровня шума - все равно с них нужно только постоянное напряжение.

Пока не установлена в гнездо микросхема фильтра MAX261, вместо нее проволочные пересмычки от входа к выходу.

А вот и обратная сторона:

Для отладки был собран макет, включающий 16 потенциометров и 4 кнопки:

Вид сбоку

И снизу

В настоящий момент столкнулся с той же проблемой, которая была и при макете, собранном на беспаечной макетке - недостаток органов управления (правда, тогда было только 3 регулятора, а теперь 16). В принципе, уже нарисовал полномасштабную переднюю панель с более 40 регулировочными ручками, но дело стопорится тем, что пока нет полной ясности с некоторыми аспектами задания общих режимов (взаимодействия между мелодическим и полифоническим синтезаторами), а также с записью и восстановлением подобранных состояний органов управления. А делать полную панель, не зная точно, что на ней будет размещено, как-то не хочется.

andriano
andriano аватар
Offline
Зарегистрирован: 20.06.2015

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

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

Arhat109-2
Offline
Зарегистрирован: 24.09.2015

Мощно..

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

andriano
andriano аватар
Offline
Зарегистрирован: 20.06.2015

Изготовление лицевой панели - вопрос, к которому пока не знаю, как подойти.

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

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

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

Кстати, шкалы там есть, только тонкими штрихами, поэтому плохо видно. Слева виден торчащий край двухстороннего скотча.

ua6em
ua6em аватар
Offline
Зарегистрирован: 17.08.2016

А почему не лазерная гравировка? Это самое оптимальное. У них и материал есть. Для изготовления файл в векторной графике

Клапауций 234
Offline
Зарегистрирован: 24.10.2016

andriano пишет:

Изготовление лицевой панели - вопрос, к которому пока не знаю, как подойти.

оракал

тащишь на рекламную фирму своё картинко и они тебе лазером режут шопопало на морду твоего прибора.

*по конструктиву - переменники-гавно, зря решил убить ими проект. я бы собирал всё на энкодерах.

Arhat109-2
Offline
Зарегистрирован: 24.09.2015

Я печатал струйником на бумагу-самоклейку. Никакого "двухстороннего скотча". Очень хорошо выглядят шкалы на визиточной бумаге - от 250гр или на фотобумаге но тоже "тяжелой" от 200-250гр. Не каждый струйник такое глотает. У меня стоял HP формата А3 - какая-то полупрофессиональная машинка, пока шестеренку не запорол, не закрепив каретку при переездах.. :(

Визиточная бумага нормально клеится на люминий клеем БФ-2, и никакого многостороннего скотча. Потом сверху ламинируется или скотчем (если размер менее 50мм - ширины рулона) или прозрачным самоклеящимся оракалом. Наклеивать, если большой размер лучше вдвоем .. но ещё лучше отдать рекламщикам, работающим с наружным оформлением транспорта. Эти ваще могут на выпукло-вогнутые поверхности оракал натягивать так, как будто "само тут росло". :)

У меня так заламинирована даже передняя панель калькулятора МК-61 с ещё "тех времен" .. все надписи как новые, насвоих местах до сих пор. Рабочий ишо..

andriano
andriano аватар
Offline
Зарегистрирован: 20.06.2015

Клапауций 234 пишет:

*по конструктиву - переменники-гавно, зря решил убить ими проект. я бы собирал всё на энкодерах.

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

Клапауций 234
Offline
Зарегистрирован: 24.10.2016

andriano пишет:

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

ок. сколько стоит качественный потенциометр для аудиотехники?

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

ты же желаешь, что бы твои крутилки отдавали контроллеру ровно то, что индицируют, а не шум и/или +-20%% ? 

andriano
andriano аватар
Offline
Зарегистрирован: 20.06.2015

Клапауций 234 пишет:

ок. сколько стоит качественный потенциометр для аудиотехники?

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

ты же желаешь, что бы твои крутилки отдавали контроллеру ровно то, что индицируют, а не шум и/или +-20%% ? 

В MIDI используется 128 градаций. Столько потенциометр (при небольшой программной поддержке) вполне способен устойчиво выдавать без шума. У меня настроена индикация изменений, - как только положение какого-то органа управления изменяется, - тут же на дисплей выдается название этого органа и новая величина. Потенциометров - 43. Если бы хотя бы один из них шумел, это бы сталу сразу заметно.

По поводу индикации - она еще более грубая - на шкале 15 штрихов.

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

Клапауций 234
Offline
Зарегистрирован: 24.10.2016

andriano пишет:

Потенциометров - 43. Если бы хотя бы один из них шумел, это бы сталу сразу заметно.

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

andriano
andriano аватар
Offline
Зарегистрирован: 20.06.2015

Будем решать проблемы по мере их поступления.

ПОка же у меня уже появляются идеи, какие следовало бы внести изменения в существующую схему.

Так что одно из двух:

- либо мне наскучит этот проект и я займусь чем-нибудь другим,

- либо созрею до того, чтобы собрать следующую модернизированную итерацию данного девайса.

andriano
andriano аватар
Offline
Зарегистрирован: 20.06.2015

В проекте обнаружился серьезный недостаток - регуляторы громкости на M62429.

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

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

Ну и избавился от микросекундных задержек, заменв их на инструкции NOP.

Результат контролировал по осциллографу.

Удалось добиться времени однократной установки уровня за 46-47 мкс при теоретическом минимуме в 11*4=44 мкс.

Собственно, этот код и публикую:

Файл A-62429.h

01///////////////////////////////////////////////////////////////////////////////
02//
03//  NEC/Renesas M62429 Digital Volume Control Driver Library for Arduino
04//
05///////////////////////////////////////////////////////////////////////////////
06 
07#ifndef _M62429_H
08#define _M62429_H
09 
10#include "Arduino.h"
11 
12#ifndef true
13#define true 1
14#endif
15 
16#ifndef false
17#define false 0
18#endif
19 
20class M62429
21{
22public:
23    void init (); //  The numbers of pins are constants due to performance
24 
25  uint16_t setVol_0 (uint8_t volume);   // was setLeft, range: from 0 dB (max) to -83 dB (min), step 1 dB
26  uint16_t setVol_1 (uint8_t volume);  // was setRight, range: from 0 dB (max) to -83 dB (min), step 1 dB
27  uint16_t setBoth (uint8_t volume);  // range: from 0 dB (max) to -83 dB (min), step 1 dB
28 
29    uint16_t setVolume (uint8_t volume, bool channel, bool both);  // from -83 to 0 step 1 dB
30};
31 
32#endif

Файл A-62429.cpp

Но основная проблема оказалась не в этом.

Шаг регулировки регулятора составляет 1дБ, что примерно соответствует пределу чувствительности человеческого уха к амплитуде сигнала. Но изменение уровня громкости происходит в произвольной фазе сигнала, что сопровождается импульсными помехами уровня примерно -20дБ. В принципе, помеха уровня -20дБ - это уже довольно много. Но в некоторых режимах она становится очень заметной.

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

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

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

Т.е. выбор остается лишь между вариантами: с какими помехами мириться, от фильтра или от усилителя.

Поэтому размышления наводят на другой вариант - регулировать громкость не цифровым регулятором громкости, а цифровым поиенциометром, имеющим гораздо более мелкие ступентки регулировки громкости, а потому и ваносящим гораздо меньшие по амплитуде помехи (порядка -50дБ). Смущает пока то, что регулятор громкости имеет диапазон регулировки более 80 дБ, а цифровой потенциометр с его 256 равномерно расположенными уровнями - лишь 46дБ. По всей видимости, нужно будет еще снабжать тракт ключами, которые бы выключали сигнал при достижении им уровня -46дБ, чтобы избавиться от паразитного сигнала в паузе.

Одновременно, цифровой поиенциометр программируется по SPI с частотой до 10 МГц. Для Ардуино доступно 4 МГц, т.е. при необходимости передать 16 бит теоретический минимум времени программирования составляет уже не 44, а лишь 4 мкс. Вероятно, на практике его можно сделать в пределах 10 мкс, что существенно меньше сегодняшних 46-47 мкс.

andriano
andriano аватар
Offline
Зарегистрирован: 20.06.2015

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

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

В качестве основы - единтственно подходящая для этой задачи плата Arduino Due. 

Компоновка - компактный блок. Уже сделанный ящик с Arduino Mega 2560 и множетвом регуляторов дополнить гнездом MIDI Out и все изменения регуляторов передавать по MIDI новому синтезатору. 

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

Все это постепенно опишу несколько позже (описывать - не так интересно, как делать) , а пока покажу интересную, на мой взгляд, картинку:

Осциллограмма цифрового и аналогового фильтров

Вверху - сигнал с выхода Arduino Due - после цифрового ФНЧ. Ступеньки дает именно он, т.к. исходный сигнал - несимметричный прямоугольник. Но на Due ЦАП достаточно высокочастотный и при частоте дискретизации 48 кГц дает ярко выраженные ступеньки (кстати, как видно на осциллограмме, фаза ступенек смещается относительно фазы сигнала, т.к. частота сигнала не кратна частоте дискретизации). А внизу - сигнал после аналогового ФНЧ второго порядка, который как раз хорошо сглаживает ступеньки сигнала.

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

Андрей_1970
Offline
Зарегистрирован: 07.07.2017

Всем доброго здравия!  Вот забрел к вам невзначай в поисках помощи советом. Дело в следующем: я дома балуюсь игрой на гармошке. На форуме гармонистов мы живем своей жизнью. У каждого из нас возникают свои идеи. В 2011 году я делал флэш програмки на компьюторе, чтобы играть гармонным звуком на клавиатуре компьютора. http://www.playcast.ru/uploads/2011/05/11/2517978.swf

 Это так, баловство для начинающих. Недавно пришла идея сделать гибрид гармонь-гитара-синтезатор. Создал тему вчера у себя на форуме  http://poigarmonika.ru/forum/index.php?topic=1050.msg59447#msg59447  и пошел в интернет в поисках реализации этого проэкта. Вот, пока добрел до вас. Смотрю, вы тут занимаетесь музакальной темой. Решил, что можете подсказать, как двигаться нам в этом проекте, с чего начать и что лучше ипользовать в конструктиве для сборки данного инструмента?

Arhat109-2
Offline
Зарегистрирован: 24.09.2015

Andriano, почитал с интересом. То есть от Меги2560 - все-таки отказались полностью, верно понял?

andriano
andriano аватар
Offline
Зарегистрирован: 20.06.2015

Arhat109-2 пишет:

Andriano, почитал с интересом. То есть от Меги2560 - все-таки отказались полностью, верно понял?

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

 

Не совсем так. Сейчас собранный на меге синтезатор планирую использовать в качестве MIDI-контроллера для софтверного синтезатора на DUE. На последнем будет только 4 переназначаемых контроллера на валкодерах, а остальные ~80 органов управления - в отдельном блоке (на Меге).

Надо только сделать MIDI-выход и переписать софт.

Теперь клавтатура будет подключаться ко входу MIDI-коньрогллера на Меге, а выход Меги (MIDI-Out, а не MIDO-Throu - что важно) - ко входу синтезатора на Due.

andriano
andriano аватар
Offline
Зарегистрирован: 20.06.2015

Андрей_1970 пишет:

 Это так, баловство для начинающих. Недавно пришла идея сделать гибрид гармонь-гитара-синтезатор. Создал тему вчера у себя на форуме  http://poigarmonika.ru/forum/index.php?topic=1050.msg59447#msg59447  и пошел в интернет в поисках реализации этого проэкта. Вот, пока добрел до вас. Смотрю, вы тут занимаетесь музакальной темой. Решил, что можете подсказать, как двигаться нам в этом проекте, с чего начать и что лучше ипользовать в конструктиве для сборки данного инструмента?

Думаю, в Вашем случае оптимальное решение - MIDI-контроллер. Т.е. у Вас будет по сути обычная MIDI-клавиатура (обычная и даже "простенькая" с точки зрения электронной начинки), отличающаяся от стандартной лишь другой формой "клавиш". Ну и чуть-чуть - софтом: на некоторые из клавиш реагировать не одной нотой, а аккордом.

Ну а контроллер, для того, чтобы был звук, нужно будет подключать к "мозгам". В простейшем случае - к софтверному синтезатору ПК. А в дальнейшем можно будет сделать и "мозги", тем более, что в Вашем случае, возможно, подойдут решения, представляющие собой одну специализированную микросхему и позиционируемые как "Музыкальный синтезатор для Ардуино". Например, dsp-G1 http://www.dspsynth.eu/

 

andriano
andriano аватар
Offline
Зарегистрирован: 20.06.2015

Вот какие сигналы порой получаешь при сбое в работе логики синтезатора:

полноразмерное изображение: http://ipic.su/img/img7/fs/Audacity_Synt_00.1521968357.png

andriano
andriano аватар
Offline
Зарегистрирован: 20.06.2015
Добился в первом приближении работоспособности синтезатора и реализовал основные возможности (в настоящий момент настраиваются 42 параметра).
Пора постепенно публиковать материалы.
Начну с управляемого генератора.
В музыкальной терминологии это называется VCO - Voltage Controlled Oscillator.
У меня, правда, не напряжением, а кодом, но не будем менять традиционную терминологию.
Частота дискретизации синтезатора 48000 Гц. На выходе генератора нужно получать прямоугольный сигнал с различной скважностью.
Проблем здесь несколько:
1. Если генерить частоту производную от частоты дискретизации (т.е. в целое число раз меньшую), о строе можно забыть, - инструмен будет безбожно фальшивить. Минимально приемлемая кратная частота примерно 1 МГц (из-за чего 16-разрядные таймеры AVR подходили практически идеально).
2. Если прменить нецелое деление, сохранив прямоугольную форму сигнала, разные периоды будут разной длительности, что приведет к джиттеру. Т.е. звук, хотя и будет попадать в ноту, будет иметь неприятные призвуки, недопустимые в качественном музыкальном инструменте.
3. Прямоугольник имеет широкий спектр частот. Часть из них неизбежно окажется выше половины частоты дискретизации, появятся зеркальные частоты, т.е. сигнал приобретет негармонические составляющие. Уровень их может достигать единиц процентов. А это даст отношение сигнал/помеха порядка -20-30 дБ, что совершенно неприемлемо.
 
В общем, если просто генерить прямогугольник прямо в цифре и потом его обрабатывать, - ничего хорошего не получится.
Что было сделано?
Был сгенерен программный прямоугольник на частоте дискретизации 1536 кГц, после чего он был пропущен через цифровой ФНЧ Бесселя 8-го порядка на 16 кГц. Т.е. получился уже не прямоугольник, а некая сглаженная волновая форма. При этом частоты 1.5 Мгц достаточно для точного воспроизведения нот. Обработка, кстати, проводилась на ПК в плавающей точке.
Дальше из этой волновой формы был вырезан только передний фронт. Он оказался длительностью 158 отсчетов. Из этого оцифрованного на частоте 1.536 МГц сигнала можно получить сигнал с частотой дискретизации 48 кГц, если брать отсчеты с шагом 32. Но самое приятное, что фазу сигнала при этом можно брать произвольно, не привязываясь к началу фронта. Т.е. получается что-то вроде DDS-синтеза, только шаг, с которым берутся отсчеты определяется не требуемой частотой генерации, а частотой среза фильтра, а потому он берется постоянным.
Сигнал при этом синтезируется (синтезируется - в прямом смысле) из кусочков: передний фронт, верхняя полка, задний фронт (вычисляемый как инверсия переднего), нижняя полка. Частоту и скважность сигнала задаем длительностью полок, а фронты имеют постоянную величину, определяемую ФНЧ. 
Фаза фронтов от импульса к импульсу изменяется, что кстати, заметно на осциллограмме в посте 33: видно, что положение ступенек на переднем и заднем фронте немного изменяются от импульса к импульсу (желтый луч осциллографа). После фильтрации обычным аналоговым ФНЧ второго порядка на ОУ ступенек не остается (синий луч осциллографа). Кстати, показаны результаты реальных измерений, а не численного моделирования.
Схема фильтра вместе с усилителем для наушников показана на рисунке. Из всех вариантов ФНЧ Бесселя второго порядка была выбрана та, что одновременно обеспечивает усиление примерно в полтора раза, т.е. как раз от размаха сигнала 3.3 В до 5 В.
 
 
Ниже приведены исходники:
 
Заголовочный файл sample.h

 

 
Файл реализации sample.cpp

 

 
И массив преднасчитанных данных (длины верхней и нижней полок для скважности 7), файл Notes.c

 

 
PS. А микросхема усилителя для наушников мне не понравилась. Она рассчитана на фиксированный коэффициент усиления около 50 и оптимизирована по количеству электролитов обвязки (при однополярном питании постоянная составляющая входного сигнала равна 0). А мне нужен был коэффициент порядка 1. Попытка поиграть с обратной связью не привела к успеху: из-за однополярного питания при заметных уровнях входного сигнала появляются большие искажения, которые ООС вне пределов питающих напряжений скомпенсировать не может. Пришлось сильно зарезать сигнал перед подачей на усилитель.
 
Arhat109-2
Offline
Зарегистрирован: 24.09.2015

Мои проздравления. Приятно читать автора, добившего тему до вменяемого результата.

andriano
andriano аватар
Offline
Зарегистрирован: 20.06.2015

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

Ну и сейчас остро стоит вопрос какой-нибудь аудио или видео демонстрации. Пока не придумал, что именно нужно.

SynthCone
Offline
Зарегистрирован: 12.07.2018

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

 

andriano
andriano аватар
Offline
Зарегистрирован: 20.06.2015

Проект продолжаться будет.

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

В настоящий момент проблемы две:

1. Заставить себя причесать исходники для публикации. А их порядка 30 файлов.

2. Придумать более или менее эффектную видео демонстрашку.

SynthCone
Offline
Зарегистрирован: 12.07.2018

Супер))

Было бы здорово если весь материал в одну статью собрать.

andriano
andriano аватар
Offline
Зарегистрирован: 20.06.2015

Думаю, в одну статью - это будет тяжеловато.

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

Так что пока буду публиковать поблочно.

Да, я тут немного переоценил законченнсть проекта: по сути более или менее законченным можно считать только звуковой модуль, управляемый от внешнего MIDI сигнала. А в проекте еще аппаратно присутствуют 5 энкодеров, 2 кнопки, экран 128х64 пикселя, а также 256 кбит EEPROM для хранения настроек. Вот в этой части еще "конь не валялся".

andriano
andriano аватар
Offline
Зарегистрирован: 20.06.2015
Тема сегоднящней заметки - управляемый фильтр.
В настоящем синтезаторе каждый генератор тона имеет свой индивидуальный фильтр, в отличие от классической схемы, где на все генераторы тона приходится один единственный фильтр. Причем, индивидуален не только тракт прохождеия сигнала, но и настройки фильтра.
Практика показывает, что если нам нужен музыкальный звук - достаточно единственного вида фильтра - ФНЧ. В данном случае используется БИХ ФНЧ второго порядка.
Вычисление коэффициентов фильтра - весьма ресурсоемкая операция. Достаточно сказать, что даже для 16-разрядного двука 32-разрядных промежуточных данных совершенно недостаточно.
Оцениваем:
- частота дискретизации - 48000 Гц,
- минимальная частота фильтра - 20 Гц,
- их отношение - 2400 раз,
- квадрат отношения - 5760000 (используется в вычислениях).
Для записи знакового числа 5760000 нужно 24 разряда. Чтобы обеспечить точность хотя бы в пределах полутона - нужно накинуть еще разряда 4 (иначе дискретность внизу будет одна октава). Итого - 28 разрядов. Ну и 16-разрядный звук, если мы с таким работаем, т.е. получается - минимум 54 разряда для вычисления произведения. Если 24-разрядный звук - практически все 64 разряда.
Кстати, для БИХ-фильтра нужно запоминать по несколько входных и выходных отсчетов. Если на входе 16-разрядный звук (реально используется 17-разрядный), столько и запоминаем. Но оказывается, что запоминать 16 разрядов выходных отсчетов - недостаточно. Фильтр работает неудовлетворительно. Поэтому нужно запоминать, минимум, 24.
Собственно, все вычисления как при настройке фильтра, так и в процессе фильтрации звука производятся в фиксированной точке. При этом для различных данных используются разные форматы. В настоящее время это:
- fixed(8.24),
- fixed(16.16),
- fixed(24.8),
- fixed(20.12),
- fixed(4.28),
- fixed(8.56) - для промежуточных вычислений.
Для уменьшения времени расчета на ПК были заранее насчитаны массивы коэффициентов, соответствующие изменению частоты фильтра на 1/8 тона по высоте (2%) и 6% - по добротности. Для двумерного массива готовых коэффициентов не хватило бы флэш-памячи, поэтому некоторый объем расчетов при настройке фильтра все-таки делать приходится.
Расчет коэффициентов (т.е. настройка фильтра) занимает 4.1 мкс.
Учитывая, что аппаратные прерывания, в которых происходит как расчет очередного сэмпла, так и перестройка фильтров, следуют с частотой 48000 Гц, их длительность не должна превышать 20.8 мкс.
Расчет трех каналов (VCO+VCF+VCA)+сумматор+ограничитель+обработка_прерывания+ЦАП занимает 6.0 мкс. В общем, на один канал (VCO+VCF+VCA) приходитсяч менее 2.0 мкс. Т.е. на расчет прохождения сигнала через фильтр - порядка 1 мкс. 
Перестроить все 3 фильтра за оставшиеся 14 мкс, учитывая, что еще надо считать несколько LFO, генераторы ADSR для каждого канала и т.п., нереально. Да и прерывания не должны занимать все 100% времени - еще нужно обрабатывать органы управления и входной поток MIDI-команд.
Поэтому фильтры рассчитываются по очереди, 6000 раз в секунду каждый.
Но об этом - позже, а пока исходники фильтров и массивы преднасчитанных констант:
 
FilterAD.h
01#ifndef FILTERAD_H
02#define FILTERAD_H
03 
04#include <Arduino.h>
05 
06extern bool FilterADdebug; // лог настройки фильтра - обязательно выключить перед loop()
07 
08class tFulter_LF2i { // ФНЧ 2-го порядка : integer(SmallInt)
09public:
10  int32_t iir32(int32_t NewSample);  // БИХ-фильтр, вычисляет один следующий отсчет  fixed(8.16) (fixed(1.16))
11  void SetFilterCoeff(double q, double f); // установка добротности и частоты ФНЧ 2-го порядка для частоты дискретизации 48000
12  void SetFilterCoeff_32(uint32_t q, uint32_t f); // установка по номеру в таблице (файлы SoftFilQ.c, SoftFilter.c)
13 
14private:
15  int32_t AC_0, AC_1, BC_1, BC_2; // коэффициенты фильтра A : fixed(8.24), B : fixed(16.16)
16  int32_t x_2, x_1, x_0; // используемые отсчеты фильтра: входные  fixed(24.8)  (fixed(17.8))
17  int32_t y_2, y_1, y_0; // используемые отсчеты фильтра: выходные fixed(16.16) (fixed(17.16))
18};
19 
20void getTimes(int &dt0, int &dt1, int &dt2, int &dt3); // статистика времеени выполнения
21 
22//       обсуждение
23// в исходном варианте
24// - сэмплы имеют тип int16_t,
25// - максимальная входная амплитуда (с учетом макс. добротности 8) составляет 4095
26// - внутри сэмпл сразу умножается на 256
27// - при использовании сэмпл с амплитудой 2047 делится на 8, т.е. макс вхолдная амплитуда составляет 255
28// предлагается переделка:
29// - избавиться внутри от умножения на 256
30// - изменить тип входного/выходного параметра на int32_t
31// - сделать макс. входную амплитуду 65535, выходную - аналогично (в конце делить на 256)
32// - после фильра делить на 256 (вероятно, при масштабировании потребуются дополнительные разряды)
33 
34#endif

 

 
FilterAD.cpp

 

 
SoftFilQ.c

 

 
SoftFilter.c

 

 
Alex Bold
Offline
Зарегистрирован: 15.09.2018

Приветствую, очень интересно продолжение. 

andriano
andriano аватар
Offline
Зарегистрирован: 20.06.2015

Да уж...

Я уже писал, что намного интереснее что-то делать, чем описывать уже сделанное.

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

По сути дела проект находится в работоспособном состоянии, при этом:

1. Физически проект состоит из двух отдельных устройств (каждое в своем корпусе и со своим блоком питания):

- MIDI-контроллер на 2560 Меге. Помимо этого в корпусе также находится полифонический MIDI-синтезатор на vs1035b.

- Цифровой MIDI-синтезатор, являющийся функциональным аналогом аналогового синтезатора на Arduino Due.

2. Первый блок:

- принимает со стандартного MIDI-входа (DIN-5) сигнал с врешней MIDI-клавиатуры и декодирует его (дабы избежать попадания добавляемых команд между байтами команд от клавиатуры),

- анализирует состояние органов управления и их изменения преобразует в MIDI-команды, попутно отображая последнее изменение на дисплее 1602,

- объединяет потоки команд с внешнего источника (MIDI-клавиатуры) и внутренних органов управления,

- разделяет MIDI-команды на два потока - один направляется на MIDI-выход, а другой - на встроенный синтезатор на vs1053b, разделение может осуществляться разными способами как с разделением клавиатуры, так и с дублированием,

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

3. Второй блок:

- анализирует входной поток MIDI-команд,

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

- в соответствии с получаемыми командами управления перестраивает собственные узлы синтеза звука,

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

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

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

5. Чего пока нет из того, что планировалось:

5.1. В MIDI-контроллере не реализованы функции записи, хранения и выбора конфигурации органов управления.

5.2. В MIDI-синтезаторе не реализованы никакие функции меню, хотя помимо 4-х настраиваемых энкодеров имеются также энкодер, две кнопки и экран для организации навигации по меню. В меню планируется настройка функций энкодеров, а также запоминание и восстановление в EEPROM многочисленных вариантов настроек.

6. В дальнейшем планируется добавить в синтезатор кольцевой модулятор.

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

 

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

sunjob
sunjob аватар
Offline
Зарегистрирован: 18.07.2013

залогинулся, что бы сказать автору !!! БРАВО !!!

удачи, терпения и пиления :о)