Прерыватель для (DR)SSTC i3.

А что мы делаем?
Аватара пользователя
BSVi
Адепт
Сообщения: 3576
Откуда: Киев

Сообщение BSVi » 30 дек 2011, 03:19

На ночь глядя, по заявкам зрителей написал трехгласый синтезатор. Четырехгласый написать тоже не сложно, но трехгласый практически полностью работает на аппаратуре, что хорошо. Хватит трех голосов? Средняя плотность равняется такой при воспроизведении одного голоса но с трехкратной частотой. Вполне возможно, что просто стоит наложить такой ограничение на ДРку. Мол - если хочешь одну ноту - то до 1кГц, если две - до 500Гц, а три - до 300Гц.

Вот как выглядит Cm (C+E?+G):
ploy.gif
ploy.gif (5.48 КБ) 24213 просмотров


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

Аватара пользователя
BSVi
Адепт
Сообщения: 3576
Откуда: Киев

Сообщение BSVi » 30 дек 2011, 18:38

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

Аватара пользователя
BSVi
Адепт
Сообщения: 3576
Откуда: Киев

Сообщение BSVi » 31 дек 2011, 12:04

Итак, написал масс сторэдж для основной программы. Было несколько очень занятных глюков. К примеру, при приеме bulk пакета, USB иногда вылетало в HardFault. Пока не поднял частоту шин APB1 и APB2 до 24МГц. В документации написано, что требуется только 8МГц на APB1, но на 12 не заработало. И 24 должно быть, почему-то, на обоих шинах. Приходится переключать тактирование всей периферии, которая работает совместно с USB.

Итак, программа без оптимизации с кластерами в 512байт выдает:
На запись: 18.6кБайт/с
На чтение: 269кБайт/с

Программа сейчас занимает 25.8кБайт

Скорость "на запись" ограничена исключительно скоростью флэшки, а на чтение - скоростью процессора.
Теперь нужно запустить файловую систему.

С новым годом вас!

Аватара пользователя
BSVi
Адепт
Сообщения: 3576
Откуда: Киев

Сообщение BSVi » 31 дек 2011, 15:14

Прикрутил файловую систему. Теперь прошивка занимает 31 кБайт. Тоесть, в 32к точно никак не влезут мои хотелки. Ну и ладненько.

Программа без оптимизации, читаются и пишутся блоки по 10 байт. Получается:
На запись: 24.3кБайт/с
На чтение: 138.5кБайт/с

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

Аватара пользователя
Intra
Сообщения: 95
Откуда: Волгоград

Сообщение Intra » 02 янв 2012, 18:28

Есть идея, как можно убрать ограничение 300 500 и 1000 Гц и отрастить полифонию до 6 нот.

в периоде волны каждой ноты, при уже известной частоте, мы получаем из блока длительности импульса значение, которое должно попадать под ограничение на каждом периоде своего импульса под значение рабочего времени ~5% от периода импульса. таким образом играя ля суб-контр октавы 27.5 Гц ограничиваются естественным значением длительности импульса из блока длительности импульса и получается 4 периода в импульсе, т.к. значение длительности импульса при периоде импульса 27.5 Гц будет естественным образом меньше 5% от периода волны этой ноты. Ля первой октавы, 440 Гц, вполне возможно может ограничится программным ограничением, если длительность импульса из блока длительности импульса будет больше значения пяти процентов от периода импульса этой ноты и может получиться 3-4 периода в импульсе. Ля третьей октавы 1720 Гц с намного большей вероятностью будет ограничена 5%-ным ограничением и её длительность будет очень мала, чтобы вызвать большое заполнение и это может вызвать один или может два периода в импульсе, а ля сорок пятой октавы не вызовет даже одного периода в импульсе прерывания и потому не будет проиграна, даже будучи звучащей перед контроллером. т.е. это естественное ограничение, которое ограничивается только лишь резонансной частотой трансформатора, от которой будет зависеть длинна одного периода в импульсе, и если нота будет слишком высокой, то попросту из за 5%-ого ограничения не вызовет даже одного периода в импульсе. однако при этом будет доступна полифония хоть трех, хоть шести нот и не придется ограничиваться от высоких частот, городить различные режимы, т.к. при длительности импульса, которая на нотах без ограничения будет делать 4 периода в импульсе, на средних и высоких нотах это будут один, два или может быть три импульса. и это не вызовет большого заполнения и нагрева.. трум пум пум всех с новым годом. ^,..,^

Аватара пользователя
Intra
Сообщения: 95
Откуда: Волгоград

Сообщение Intra » 02 янв 2012, 18:28

а так же вот тут есть немного интересного по этой теме. http://uzzors2k.4hv.org/index.php?page=midiinterrupter

Аватара пользователя
BSVi
Адепт
Сообщения: 3576
Откуда: Киев

Сообщение BSVi » 02 янв 2012, 23:09

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

Это фундаментальное ограничение. Физически невозможно сыграть много звуков, не увеличивая эффективную частоту сигнала.

А чем плоха 3х голосая полифония? Тесла выдает слишком широкополосный аудиосигнал, чтобы в нем хорошо различать звуки.

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

Теперь меню можно писать вот так:

Код: Выделить всё

class ContrastChanger : public INotificable
{
public:
    int32 contrast;
   
    ContrastChanger()
    {
        contrast = 20;   
    }
   
    virtual void OnParamChanged()
    {
        Display::SetContrast(contrast);
    }
};

ContrastChanger contrast_changer;

//---------------------------------------------------------------------------
void BuildMainMenu()
{
    IntMenuItem  contrast_item("contrast", 3, &contrast_changer.contrast, 0, 100, 1, &contrast_changer);
    TextMenuItem pw_limit_item("PW limit");
    TextMenuItem freq_limit_item("Frequency limit");
   
    Menu<3> setup("Setup", true);
    setup.Add(&contrast_item);
    setup.Add(&pw_limit_item);
    setup.Add(&freq_limit_item);
   
    Menu<5> menu("", false);
    menu.Add(&setup);   
   
    menu.Enter();
}


uzzor'а я знаю, но у него SSTC, а не DRSSTC. Там все намного проще.

Аватара пользователя
Intra
Сообщения: 95
Откуда: Волгоград

Сообщение Intra » 03 янв 2012, 17:11

Я неправильно объяснил.

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

По поводу снятия ограничений 300 500 и 1000 Гц я имел ввиду введение циклов пересчёта длительности импульса для каждой из нот в отдельности. Сначала длительность импульса считается из расчёта 5% от периода, как у uzzors2k в Compare Values Generator, потом те импульсы, длительность которых превышает общую установленную длительность, ограничиваются порогом общей длительности импульса. таким образом те ноты, которые внизу играются со стандартной длительностью, с которой игрались бы, будучи ограниченны мультивибратором, ограничиваются микроконтроллером до порога, до которого ограничивались бы, играясь через общее ограничение мультивибратором, а те, которые далеко на верху не вызовут даже одного периода работы моста - вообще не будут проигрываться, сохраняя звучание в порядке на верхнем регистре, т.к. средние ноты, а также нижние ноты высокого регистра будут ограничиваться программно до нужного, общему делу, заполнения. Это не фундаментальное, а принципиальное ограничение. мы будем ограничивать целую ноту, а не части импульсов ей принадлежащие или частично убирая импульсы. ни в коем случае. это нарушит частоту её звучания, т.к. частота звучания зависит от точной последовательности этих импульсов)). просто полностью убирается нота, там, где её звучание не создаст хотя бы одного периода работы моста с учётом расчёта 5%-ого ограничения. вообще, если держать любую ноту в ограничении длительности импульса равной 5% то очень просто вычислить - сколько процентов заполнения будет если добавлять полифонию. для одной ноты это 5% для любого из интервалов любой частоты второй ноты интервала это всё равно такие же 5% и 5+5=10% заполнения. соответственно 3 ноты - 15% и 4 ноты - 20%. 4 ноты конечно перебор, хватит и трёх, в конце концов перыватель можно сделать двойным, где каждый мк робит для только одной теслы и если тесел две, то и микроконтроллеров будет тоже два. а это уже 6-нотная полифония и бах во всём его величии. и это при любой частоте звучания. разве это не прекрасно? на практике же это будет выглядеть примерно так. низкие ноты переползая в высокие будут визуально уменьшать стриммер и уменьшать громкость звучания на высоких частотак, но не очень сильно, потому что высокие частоты всегда громче низких ;-) , а т.к. где-то в средних частотах вроде ля первой октавы стример увеличивается от низких к средним при одинаковой длительности импульса для всех нот, то уменьшение будет компенсировать увеличение и это конечно не будет ровно, но в среднем, стример всего нижнего и среднего регистра будут примерно одинакового размера, а существенное визуальное уменьшение стримера будет лишь в верхнем регистре. И выглядеть это будет примерно вот так.. http://www.youtube.com/watch?v=dHI4E9d0U7I если присмотреться, то в начала песни когда гитара два раза уходит далеко на верх, где то около третьей октавы, стример скукоживается..

Вообще, если уж использовать цифру, а не аналог, то выжимать нужно всю эту цифру на полную мощность. Можно увести в цифру практически всё, что исполняется через внешние детали и упростить схемотехнику до вот такого http://www.flickr.com/photos/48266659@N ... otostream/
Ведь основной здравый смысл заморачиваться с музыкальностью теслы в том, чтобы сделать из неё музыкальный инструмент с максимальными возможностями при максимально упрощённой реализации.

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

Аватара пользователя
BSVi
Адепт
Сообщения: 3576
Откуда: Киев

Сообщение BSVi » 04 янв 2012, 11:25

Ага, понял. Ты предлагаешь сделать ограничение по средней плотности импульсов, изменяя ширину импульса.

Плотностью импульсов я буду называть такую величину: Плотность = Время включения теслы/Период.
Если периодом выбрать 1сек, то Плотность = Ширина импульса * Частота прерывателя.

Итак, сейчас я вижу 4 варианта ограничения:
  1. Использовать общее ограничение. То есть, если в настройках установили 1000гц/200мкс то каждая из нот будет ограничиваться так. Это опасный вариант.
  2. Делить частоту максимальной ноты на количество воспроизводимых нот. Если звучит одна нота, то ее частота может быть до 1000гц, если две - то до 500, итп.
  3. Ограничивать сумму частот. Если сумма установлена 1000гц, то одна нота может быть 20гц, а другая - 980, или две по 500Гц, скважность общая. В таком варианте средняя плотность импульсов ограничена произведением (сумма*длительность).
  4. Ограничивать плотность. При этом запускаются любые ноты до максимальной частоты теслы, но воспроизводятся с такой длительностью, чтобы внутри некоторого интервала плотность не превышала заданную.

Мне больше всего нравится третий вариант. В отличии от 4-ого, в нем можно контролировать громкость ноты. И могут звучать низкие и высокие ноты одновременно. Кто что думает?

Аватара пользователя
Intra
Сообщения: 95
Откуда: Волгоград

Сообщение Intra » 04 янв 2012, 13:11

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

Ограничивая длительность импульса каждой из нескольких воспроизводимых нот в отдельности по определённому, равному для всех отношению рабочего и мёртвого времени (5%/100%) мы получаем на любой частоте одинаковую плотность, если играем одну ноту и играя две три или четыре ноты одновременно мы просто складываем 5% плотности каждой ноты между собой и получаем 10% 15% или 20% плотности от общего рабочего времени теслы. Нет смысла ограничиваться частотами, когда ты контролируешь каждую из частот и держишь её на своём месте.

Плотностью я называю сумму отношений единиц меандра к их нулям на выходе прерывателя. допустим у нас нота ля 440 единиц меандра за секунду. некоторый интервал о котором идёт речь мы примем за секунду. итого. при воспроизведении одной ноты у нас за секунду 440 импульсов, длинна каждого из которых равна пяти процентам от периода работы этих импульсов. 1сек/440имп=0,00227(27) секунд = длинна одного периода. и её мы теперь делим на 5% длинны импульса и 95% пустоты. 0,00227(27)*0.05=~0.0001136(36) секунд - длинна импульса для ноты ля первой октавы. если общее ограничение 0.000025 секунд, как у меня, то т.к. длительность ноты ля получается 113 мкс, которые больше 25мкс, то 113 мкс уменьшаются до 25 мкс, тем самым плотность сигнала уменьшается с 5% до 1.106% и становится ещё более разряженной. теперь возьмём ля суб-контр октавы. 27.5 Гц. 1/27.5=0.036(36) секунд период из которых 5% рабочего времени будут слишком большие. 0,036*0,05=0,0018 секунд. 1800 микросекунд тоже больше 25-ти. поэтому вторичное ограничение так же ограничивает эту ноту до нужной нам длительности. теперь возьмём ля где нибудь на четвёртой октаве. 3440 Гц. период будет равен 1/3440=0.000290697674 где пять процентов это 0,0000145348837 и это 14 микросекунд. 14 микросекунд меньше 25-ти и поэтому вторично не ограничивается. при этом за одну секунду плотность любой ноты не превышает 5% а плотность четырёх нот не превышает 20-ти. остаётся только рассчитать отношение плотности к нагреву ключей и узнать какая плотность максимальна для определённых ключей. а также наверное убрать из диапазона сверхвысокие звуки начиная с до пятой октавы. низкие же звуки лучше не ограничивать, потому что на них можно сделать хорошие визуальные эффекты при помощи миди.

Громкость ноты в тесле - понятие очень сильно относительное.
Во-первых. Тесла - это вообще очень громкий инструмент и даже когда стример 10 сантиметров он достаточно слышен на близком расстоянии
Во-вторых. Контроль над громкостью на уровне теслы можно получить, если дополнительно изменять длительность импульса в широких пределах, если это возможно, потому как громкость на уровне теслы меняется ступенчато. по периодам. и если у тебя 4 периода, то это слишком жёсткие ступени, а если 45 периодов, то конечно переход будет достаточно плавным. вот у меня к примеру 4-6 периодов и эта фича будет мало полезна.. хотя.. может быть и не так уж бесполезна. однако, также стоит учесть психоакустический эффект. нужно просчитать слуховое восприятие стримера на всех частотах при разном расстоянии от теслы до уха, построить график, и писать алгоритм громкости уже исходя из этого графика, потому что если не будет учтён этот эффект, то результат не оправдает ожидания.
И в третьих. Громкость можно регулировать на уровне миди, что подходит под четвёртый вариант реализации. Когда ты пальцами играешь по MIDI клавиатуре, нажимая аккуратно и мягко синтезатор выдаёт piano. когда резко и сильно - синтезатор выдаёт forte. реализацию громкости на уровне миди можно сделать, расшифровывая значения громкости и пересчитывая значения длительности импульса в необходимых пределах для каждой ноты в отдельности. в общем, собрать воедино эту последовательность довольно гемморно, но не невозможно.

Aneg
Сообщения: 17
Откуда: Украина

Сообщение Aneg » 04 янв 2012, 19:17

Когда говорится про ДР, то какая микросхема имеется ввиду?

Аватара пользователя
BSVi
Адепт
Сообщения: 3576
Откуда: Киев

Сообщение BSVi » 04 янв 2012, 19:27

Aneg, никакая DRSSTC - это вид теслы. http://drsstc.com/

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

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

Переписал меню на связные списки, оно стало теперь красиво выглядеть, хоть и занимать дофига оперативки. Теперь нуно потихоньку переходить к функциональности. С использованием placement new, меню собирается примерно вот так:

Код: Выделить всё

        IntMenuItem  *voices_max = new(&menu_memory) IntMenuItem("Voices",                  1, 1,  3,       &menu_memory);
        IntMenuItem  *pw_max     = new(&menu_memory) IntMenuItem("PW limit",                4, 1,  9990,    &menu_memory);
        Menu *setup              = new(&menu_memory) Menu("Setup", true);
        setup->Add(voices_max);
        setup->Add(pw_max);
        main_menu->Add(setup);

Аватара пользователя
BSVi
Адепт
Сообщения: 3576
Откуда: Киев

Сообщение BSVi » 05 янв 2012, 16:03

Закрыл сегодня аж 6ть пунктов.

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

Аватара пользователя
BSVi
Адепт
Сообщения: 3576
Откуда: Киев

Сообщение BSVi » 05 янв 2012, 17:45

Уже 7 пунктов :) И следующий будет - адскиэпичный модулятор. Предположительное меню для него вот такое будет:

  • Voices
  • Freq 1
  • PW 1
  • Freq 2
  • PW 2
  • Freq 3
  • PW 3
  • Mod 1 freq
  • Mod 1 PW
  • Mod 2 freq
  • Mod 2 PW
  • Single shoot

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

Стоит ли такого монстра городить?

Аватара пользователя
Intra
Сообщения: 95
Откуда: Волгоград

Сообщение Intra » 06 янв 2012, 15:44

BSVi писал(а):Стоит ли такого монстра городить?


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

Аватара пользователя
BSVi
Адепт
Сообщения: 3576
Откуда: Киев

Сообщение BSVi » 06 янв 2012, 16:35

Полагаю вопрос риторический?

Да нет, не риторический, я его уже практически написал, если бы не одно "но".

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

Я стараюсь все упростить, но требований довольно много и совсем просто не получится. Реально будет два варианта - одни попроще, другой побогаче возможностями.

А ну, как что за глючит на концерте? XD

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

Код: Выделить всё

-------------------------------------------------------------------------------
Language                     files          blank        comment           code
-------------------------------------------------------------------------------
C                               30           1476           2785          37575
C/C++ Header                    62           2589           4118          10383
Assembly                        10            581            563           2676
C++                             23            465            506           1922
Python                           1             21             13            511
DOS Batch                        2              8              0             22
-------------------------------------------------------------------------------
SUM:                           130           5185           7985          53089
-------------------------------------------------------------------------------


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

А теперь о наших баранах. Это пипец :( Закончилась оперативка. Виной тому - жирное меню, написанное в лучших традициях ООП. Придется переписывать его третий раз. А я уже раскрыл рот - мол "проц жирный, все выдержит".

Аватара пользователя
BSVi
Адепт
Сообщения: 3576
Откуда: Киев

Сообщение BSVi » 06 янв 2012, 21:55

Фууух, переписал меню в табличную форму. Практически день убил. Уххххх......

Aneg
Сообщения: 17
Откуда: Украина

Сообщение Aneg » 07 янв 2012, 00:09

Закончилась оперативка или флеш память :?:

Аватара пользователя
BSVi
Адепт
Сообщения: 3576
Откуда: Киев

Сообщение BSVi » 07 янв 2012, 00:56

Оперативка. Флэшки еще 20кБ :) Но после переписывания меню 2кБ освободилось. Да еще и стэки у меня жирные, нужно бы их пообрезать, но пока руки не дошли.

Aneg
Сообщения: 17
Откуда: Украина

Сообщение Aneg » 07 янв 2012, 01:07

А после урезания стеков, сколько еще освободиться как думаешь?

Аватара пользователя
BSVi
Адепт
Сообщения: 3576
Откуда: Киев

Сообщение BSVi » 07 янв 2012, 01:14

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

Аватара пользователя
BSVi
Адепт
Сообщения: 3576
Откуда: Киев

Сообщение BSVi » 07 янв 2012, 04:49

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

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

Код: Выделить всё

    using namespace Menu;
    const MenuItem menu_items[] =
    {
        {IntMenu, { 
            .intmenu.name = "Voices",
            .intmenu.on_enter_press = Enter,
            .intmenu.id = 0,
            .intmenu.positions = Config::voices_positions,
            .intmenu.min       = &Config::voices_min,
            .intmenu.max       = &Config::system.voices_max,
            .intmenu.value     = (uint32*)&params.voices,
            .intmenu.on_change = 0}
        },       
       
        {IntMenu, { 
            .intmenu.name = "1st freq",
            .intmenu.on_enter_press = Enter,
            .intmenu.id = 0,
            .intmenu.positions = Config::freq_positions,
            .intmenu.min       = &Config::freq_min,
            .intmenu.max       = &Config::system.freq_max,
            .intmenu.value     = (uint32*)&params.voice_freq[0],
            .intmenu.on_change = FreqChanged}
        },

        {IntMenu, { 
            .intmenu.name = "1st PW",
            .intmenu.on_enter_press = Enter,
            .intmenu.id = 0,
            .intmenu.positions = Config::pw_positions,
            .intmenu.min       = &Config::pw_min,
            .intmenu.max       = &Config::system.pw_max,
            .intmenu.value     = (uint32*)&params.voice_pw[0],
            .intmenu.on_change = 0}
        },

        {IntMenu, { 
            .intmenu.name = "2nd freq",
            .intmenu.on_enter_press = Enter,
            .intmenu.id = 1,
            .intmenu.positions = Config::freq_positions,
            .intmenu.min       = &Config::freq_min,
            .intmenu.max       = &Config::system.freq_max,
            .intmenu.value     = (uint32*)&params.voice_freq[1],
            .intmenu.on_change = FreqChanged}
        },

        {IntMenu, { 
            .intmenu.name = "2nd PW",
            .intmenu.on_enter_press = Enter,
            .intmenu.id = 0,
            .intmenu.positions = Config::pw_positions,
            .intmenu.min       = &Config::pw_min,
            .intmenu.max       = &Config::system.pw_max,
            .intmenu.value     = (uint32*)&params.voice_pw[1],
            .intmenu.on_change = 0}
        },

        {IntMenu, { 
            .intmenu.name = "3rd freq",
            .intmenu.on_enter_press = Enter,
            .intmenu.id = 2,
            .intmenu.positions = Config::freq_positions,
            .intmenu.min       = &Config::freq_min,
            .intmenu.max       = &Config::system.freq_max,
            .intmenu.value     = (uint32*)&params.voice_freq[2],
            .intmenu.on_change = FreqChanged}
        },

        {IntMenu, { 
            .intmenu.name = "3rd PW",
            .intmenu.on_enter_press = Enter,
            .intmenu.id = 0,
            .intmenu.positions = Config::pw_positions,
            .intmenu.min       = &Config::pw_min,
            .intmenu.max       = &Config::system.pw_max,
            .intmenu.value     = (uint32*)&params.voice_pw[2],
            .intmenu.on_change = 0}
        },


        {IntMenu, { 
            .intmenu.name = "1st On time, ms",
            .intmenu.on_enter_press = Enter,
            .intmenu.id = 0,
            .intmenu.positions = Config::modulator_positions,
            .intmenu.min       = &Config::modulator_min,
            .intmenu.max       = &Config::modulator_max,
            .intmenu.value     = (uint32*)&params.mod_on[0],
            .intmenu.on_change = 0}
        },


        {IntMenu, { 
            .intmenu.name = "1st Off time, ms",
            .intmenu.on_enter_press = Enter,
            .intmenu.id = 0,
            .intmenu.positions = Config::modulator_positions,
            .intmenu.min       = &Config::modulator_min,
            .intmenu.max       = &Config::modulator_max,
            .intmenu.value     = (uint32*)&params.mod_off[0],
            .intmenu.on_change = 0}
        },
       
        {IntMenu, { 
            .intmenu.name = "2nd On time, ms",
            .intmenu.on_enter_press = Enter,
            .intmenu.id = 0,
            .intmenu.positions = Config::modulator_positions,
            .intmenu.min       = &Config::modulator_min,
            .intmenu.max       = &Config::modulator_max,
            .intmenu.value     = (uint32*)&params.mod_on[1],
            .intmenu.on_change = 0}
        },


        {IntMenu, { 
            .intmenu.name = "2nd Off time, ms",
            .intmenu.on_enter_press = Enter,
            .intmenu.id = 0,
            .intmenu.positions = Config::modulator_positions,
            .intmenu.min       = &Config::modulator_min,
            .intmenu.max       = &Config::modulator_max,
            .intmenu.value     = (uint32*)&params.mod_off[1],
            .intmenu.on_change = 0}
        },

        {IntMenu, { 
            .intmenu.name = "3rd On time, ms",
            .intmenu.on_enter_press = Enter,
            .intmenu.id = 0,
            .intmenu.positions = Config::modulator_positions,
            .intmenu.min       = &Config::modulator_min,
            .intmenu.max       = &Config::modulator_max,
            .intmenu.value     = (uint32*)&params.mod_on[2],
            .intmenu.on_change = 0}
        },


        {IntMenu, { 
            .intmenu.name = "3rd Off time, ms",
            .intmenu.on_enter_press = Enter,
            .intmenu.id = 0,
            .intmenu.positions = Config::modulator_positions,
            .intmenu.min       = &Config::modulator_min,
            .intmenu.max       = &Config::modulator_max,
            .intmenu.value     = (uint32*)&params.mod_off[2],
            .intmenu.on_change = 0}
        },


        {IntMenu, { 
            .intmenu.name = "Single shoot",
            .intmenu.on_enter_press = Enter,
            .intmenu.id = 0,
            .intmenu.positions = 1,
            .intmenu.min       = &Config::zero,
            .intmenu.max       = &Config::one,
            .intmenu.value     = (uint32*)&params.ss,
            .intmenu.on_change = 0}
        },

        {TextMenu, {
            .textmenu.name = "Save",
            .textmenu.on_enter_press = Save},
        },
       
        {Exit},
    };


Если не придумаю, что еще бы можно было с ним сделать, начну заниматься интересным - midi :)

Аватара пользователя
Intra
Сообщения: 95
Откуда: Волгоград

Сообщение Intra » 07 янв 2012, 13:39

Частоты двух одновременно звучащих нот никогда не могут совпасть. ты видимо говоришь об октавных частотах?

Аватара пользователя
Intra
Сообщения: 95
Откуда: Волгоград

Сообщение Intra » 07 янв 2012, 13:49

Оптимизация кода - важная стадия процесса. =)
Всех с рождеством!

Аватара пользователя
BSVi
Адепт
Сообщения: 3576
Откуда: Киев

Сообщение BSVi » 07 янв 2012, 17:04

Частоты двух одновременно звучащих нот никогда не могут совпасть. ты видимо говоришь об октавных частотах?

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

Немного дописал меню. Появились варианты выбора с текстом текстом (типа yes/no). Вообще, мне нифига не нравится как сейчас меню устроенно, зато оно быстрое и компактное.

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

Сделал ускорение инкремента/декремента цифр при удержании кнопки. Стало удобнее.

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

Теперь миди. Ситуацию омрачняет то, что никаких миди-девайсов у меня сейчас нет :(

Вернуться в «Наши проекты»



Кто сейчас на конференции

Сейчас этот форум просматривают: нет зарегистрированных пользователей и 71 гость