RU EN
Main Page Download Addons Forum Blog Feedback
News: AIMP для Android — политика доступа к файлам
 
0 Members and 1 Guest are viewing this topic. Previous topic - Next topic

Aleksandr009

Сделал 3-хполосный темброблок (эквалайзер). Кривая - синусоида.

Black_AVP_Bim

#1
За энтузиазм уже +1 поставил.

Aleksandr009

Quote from: Black_AVP on September 27, 2016, 17:41:14
За энтузиазм уже +1 поставил.
Кривая, конечно, далека от нужной. Таких изломов не должно быть. У ВЧ-фильтра она вообще получилась зеркальной.
АЧХ каждого фильтра имеет форму, близкую к параболе, симметричную относительно центральной частоты.
Чтоб было понятнее, набросал несколько вариантов сочетаний разных положений регуляторов.
Спасибо. Но это было пока так для примера. Про форму и сам догадался. Также думаю, что при симметрии это не парабола, а скорее синусоида.
Теперь надо подумать как-бы это рассчитать.

Aleksandr009

О да! Я это смог сделать!  ;D
Идеальная кривая - синусоида. Для расчёта коэффициентов использовал 2 синусоиды - 0.5+0.5sin(pi*x/9-pi/2) и 0.5+0.5sin(pi*x/8-pi/2).

Обновил файл в первом посте!

Aleksandr009

#4
Ещё немного обновил!
       
Не сразу мысль пришла что формулу синусоиды можно прямо в скрипт запихнуть. Теперь расчёт будет поточнее. 

Black_AVP_Bim

Молодец, Александр! Жаль, плюсик пока не поставить - сутки не прошли. В твоём возрасте мне тоже казалось, что ничего невозможного на свете нет.
Скрипт можно ещё немного оптимизировать, если вспомнить про циклы, писанины будет меньше.
Для ВЧ-фильтра вместо 8-ми строчек это будет выглядеть так:

for N:= 1 to 8 do
  EQ.Set('BandValue' + IntToStr(N + 10), (((State - 1499)/200 * (1 + sin(pi * N / 8 - pi/2))) + ((M - 1499)/200 * (1 + sin(pi * (8 - N) / 8 - pi/2)))));

Но, остаётся одна маленькая неприятность: пользователь может из диалога DSP изменить твою АЧХ любым движком, в своём 2-полосном я это дело заблокировал.
Жаль, что в наших скинах аппаратуры это не применить - трёхполосные регуляторы тембра, практически, не встречаются.
Как вариант, можно было пойти несколько по другому пути: регуляторы подключить не к скрипту, а к нужным полосам эквалайзера 31, 1к, 16к, а в скрипте считывать эти значения, тогда скрипт окажется независимым от State (возможно, даже, будет один на всё) и блокировать регуляторы будет проще.

Aleksandr009

Quote from: Black_AVP on September 28, 2016, 17:03:18
Spoiler
Молодец, Александр! Жаль, плюсик пока не поставить - сутки не прошли. В твоём возрасте мне тоже казалось, что ничего невозможного на свете нет.
Скрипт можно ещё немного оптимизировать, если вспомнить про циклы, писанины будет меньше.
Для ВЧ-фильтра вместо 8-ми строчек это будет выглядеть так:

for N:= 1 to 8 do
  EQ.Set('BandValue' + IntToStr(N + 10), (((State - 1499)/200 * (1 + sin(pi * N / 8 - pi/2))) + ((M - 1499)/200 * (1 + sin(pi * (8 - N) / 8 - pi/2)))));

Но, остаётся одна маленькая неприятность: пользователь может из диалога DSP изменить твою АЧХ любым движком, в своём 2-полосном я это дело заблокировал.
Жаль, что в наших скинах аппаратуры это не применить - трёхполосные регуляторы тембра, практически, не встречаются.
Как вариант, можно было пойти несколько по другому пути: регуляторы подключить не к скрипту, а к нужным полосам эквалайзера 31, 1к, 16к, а в скрипте считывать эти значения, тогда скрипт окажется независимым от State (возможно, даже, будет один на всё) и блокировать регуляторы будет проще.

Спасибо!  Оптимизацией может позже займусь.

И хотел узнать как вы у себя заблокировали в 2-полосном?



Black_AVP_Bim

Да, ещё, если вспомнить формулы приведения из школьной тригонометрии, вычисления ещё можно несколько упростить:
sin(a - pi/2) = - cos(a).

Quote from: Aleksandr009 on September 28, 2016, 18:03:11
И хотел узнать как вы у себя заблокировали в 2-полосном?
Вот тут, как раз коммутаторы и понадобятся. Надо собрать значения всех бендов эквалайзера, просуммировать их, а результат подать на скриптовый счётчик. Получится, что он будет срабатывать при любом изменении любой полосы. В этом месте я как раз на грабли попервости и наступил - ошибся с модулем счётчика.  Хотя на самом деле всё просто: биндинг возвращает значения в диапазоне -1500..0..1500, умножить на 18, получим 27000, и столько же прибавить (в общем коммутаторе), чтобы результат не был отрицательным - для счётчика это недопустимо. Получается, что модуль должен быть не менее 54000.

Black_AVP_Bim

Кстати, подобным образом, наверное, можно построить и 5- и 7-полосный эквалайзер - вот это уже будет более актуально и востребовано.
А если получится, можно пойти и дальше - сделать эквалайзер с изменяемым числом полос по желанию поьзователя.

Aleksandr009

Quote from: Black_AVP on September 28, 2016, 18:55:41
Кстати, подобным образом, наверное, можно построить и 5- и 7-полосный эквалайзер - вот это уже будет более актуально и востребовано.
А если получится, можно пойти и дальше - сделать эквалайзер с изменяемым числом полос по желанию поьзователя.
Да, построить и 5- и 7-полосный (ну и другое число) эквалайзер будет легко- надо лишь изменить дробь под число полос.
А вот второе будет очень сложно.

Aleksandr009

Добавил версию с оптимизированными скриптами!

Black_AVP_Bim

Quote from: Aleksandr009 on September 29, 2016, 14:18:47
Добавил версию с оптимизированными скриптами!
Так, конечно, лаконичнее смотрится. Осталось ещё лишние скобки покуцать.
Но, что интересно, я вчера ещё попробовал оптимизировать твой скрипт, правда, дальше ВЧ-фильтра не ушёл, вышло так:
  for N:= 1 to 8 do
    EQ.Set('BandValue' + IntToStr(N + 10), ((State - 1499) * (1 - cos(pi * N /8)) +
      (M - 1499) * (1 - cos(pi * (8 - N) /8))) / 200);

Старался, всё-таки, следовать законам тригонометрии, что sin(a - pi/2) = - cos(a), а в твоём примере, вижу, что остался "+". У меня с плюсом не работает, а утебя с минусом. В чём загадка?
И ещё, почему в некоторых местах вычитается константа 1499, а вдругих - 1500. Правда эта единичка на результате, практически, не скажется.

Aleksandr009

Quote from: Black_AVP on September 29, 2016, 15:52:31
Так, конечно, лаконичнее смотрится. Осталось ещё лишние скобки покуцать.
Но, что интересно, я вчера ещё попробовал оптимизировать твой скрипт, правда, дальше ВЧ-фильтра не ушёл, вышло так:
  for N:= 1 to 8 do
    EQ.Set('BandValue' + IntToStr(N + 10), ((State - 1499) * (1 - cos(pi * N /8)) +
      (M - 1499) * (1 - cos(pi * (8 - N) /8))) / 200);

Старался, всё-таки, следовать законам тригонометрии, что sin(a - pi/2) = - cos(a), а в твоём примере, вижу, что остался "+". У меня с плюсом не работает, а утебя с минусом. В чём загадка?
И ещё, почему в некоторых местах вычитается константа 1499, а вдругих - 1500. Правда эта единичка на результате, практически, не скажется.
Подправил всё.
Загадок нет! А из тригонометрии почти ничего не помню так как про неё не вспоминал давно. Просто я коэффициенты N поменял местами в сумме.
1499 пропустил не исправил везде должно быть 1500, так как при 1499 минимальное значение регуляторов -14.99dB.

Black_AVP_Bim

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

Aleksandr009

Quote from: Black_AVP on September 29, 2016, 16:30:46
Вся наша оптимизация в скриптах сводится, в основном, к сокращению писанины, а скрипт-движок её всё одно сожрёт - ни быстрее, ни медленнее работать в скине не будет, так что, особо с этим заморачиваться не стОит.
+1 тебе ещё за труды.
Сейчас вроде-бы уже некуда оптимизировать.
Спасибо и вам за советы!