gammaker
> Или в одном коротком периоде нельзя задать разные фазы гармоник?
Именно так.
gammaker
> В идеале хотелось бы, чтобы имея константный периодический семпл, двигаться по
> нему по кругу, параллельно записывая обработанный фильтром результат в выходной
> массив - один проход без каких-либо никаких промежуточных массивов. И по мере
> прохода фильтр должен модифицироваться так, чтобы отсекать всё больше и больше
> высоких частот.
То есть ты хочешь не переписывать исходный сигнал, а постепенно менять параметры самого фильтра? Это возможно, но проблему с кратностью гармоник не решит. Обычный резонансный фильтр на основной тон с плавным повышением добротности должен сработать. Только нужно учитывать, что резонансный фильтр увеличивает громкость, придётся искусственно плавно её снижать.
gammaker
> А откуда брать этот уровень реверберации? Он может прямо в MIDI задаваться?
> Есть какое-то событие MIDI, которое за это отвечает?
Есть. В миди редакторах это называют "контроллеры", там №91 - это ревер, №93 - хорус. Контроллером №7 ты, по идее, уже пользуешься - это громкость (не путать с велосити).
Mikle
> То есть ты хочешь не переписывать исходный сигнал, а постепенно менять
> параметры самого фильтра? Это возможно, но проблему с кратностью гармоник не
> решит.
Да. Я рассматриваю этот способ не только для гитары, а для многих моих инструментов, которые я уже синтезирую через FFT и хочу скрестить с субтрактивным синтезом.
Через FFT у меня генерируется достаточно длинный сигнал из множества гармоник с рандомными фазами. Откуда там возьмётся проблема с кратностью гармоник?
Mikle
> Обычный резонансный фильтр на основной тон с плавным повышением добротности
> должен сработать.
Я так понимаю, надо будет постоянно пересчитывать коэффициенты? Если я буду это делать каждый N семплов, не будет ли щелчков? Насколько это всё непрерывно и устойчиво?
>Только нужно учитывать, что резонансный фильтр увеличивает громкость, придётся искусственно плавно её снижать.
А по какому закону? Экспонента какая-нибудь?
Mikle
> Есть. В миди редакторах это называют "контроллеры", там №91 - это ревер, №93 -
> хорус. Контроллером №7 ты, по идее, уже пользуешься - это громкость (не путать с велосити).
Да, 7-й использую, теперь понятно, где смотреть, спасибо. Но многие ли MIDI их используют? А то сделаю, а потом окажется, что реверберация в сторонних MIDI почти нигде не встречается и никакого толку. Либо как-то самому на стороне синтезатора в этом случае настраивать реверберацию.
gammaker
> Через FFT у меня генерируется достаточно длинный сигнал из множества гармоник с
> рандомными фазами. Откуда там возьмётся проблема с кратностью гармоник?
Проблема не в значении фазы, а в том, что она не меняется. Если ты генерируешь гармоники только с кратными частотами, то не важно, какие там фазы, а если частоты не кратны основному тону, то могут быть проблемы с щелчком при зацикливании.
gammaker
> Я так понимаю, надо будет постоянно пересчитывать коэффициенты? Если я буду это
> делать каждый N семплов, не будет ли щелчков? Насколько это всё непрерывно и
> устойчиво?
А почему не каждый сэмпл? Там же по одному умножению на коэффициент выходит.
gammaker
> А по какому закону? Экспонента какая-нибудь?
По тому же, по какому прибавляешь добротность.
gammaker
> Но многие ли MIDI их используют? А то сделаю, а потом окажется, что
> реверберация в сторонних MIDI почти нигде не встречается и никакого толку.
№№ 91 и 93 используются практически повсеместно.
Mikle
> Проблема не в значении фазы, а в том, что она не меняется. Если ты генерируешь
> гармоники только с кратными частотами, то не важно, какие там фазы, а если
> частоты не кратны основному тону, то могут быть проблемы с щелчком при
> зацикливании.
У меня все гармоники - это не одна частота, они распределены по Гауссу в некотором интервале частот. Например для частоты гармоники 440 Гц будут заданы все частоты из интервала (например 437-443 Гц), которые можно представить массивом частот выбранного размера. И у каждой такой частоты своя рандомная фаза. Так что видимо у меня ни одной из этих проблем не должно быть.
Mikle
> А почему не каждый сэмпл? Там же по одному умножению на коэффициент выходит.
В фильтре, который я находил, как-то сложно считались коэффициенты. Если у тебя есть такой простой фильтр, где можно менять добротность одним умножением, поделишься кодом?
Как вообще действует добротность? Правильна ли моя догадка, что независимо от её значения, она не трогает частоты ниже указанного порога, и её значение пропорционально скорости затухания частот выше порога в децибелах? Хотя наверное должен быть какой-то подвох, иначе один такой фильтр был бы идеальным и более сложных не было бы.
Mikle
> №№ 91 и 93 используются практически повсеместно.
Отлично, тогда постараюсь поскорее их прикрутить. Такой простенький алгоритм подойдёт?
gammaker
> У меня все гармоники - это не одна частота, они распределены по Гауссу в
> некотором интервале частот. Например для частоты гармоники 440 Гц будут заданы
> все частоты из интервала (например 437-443 Гц)
Так быть не может. В сэмпле с длительностью X могут быть гармоники только с периодами, кратными X. То есть, например, в секундном сэмпле могут быть только целые частоты - 403 Гц или 188 Гц, но не 344.6. В двухсекундном могут быть уже половинки - 33.5 Гц, но не 33.75.
gammaker
> Правильна ли моя догадка, что независимо от её значения, она не трогает частоты
> ниже указанного порога
Нет, она поднимает уровень частот, более близких к резонансу (с любой стороны), ничего не опускает.
gammaker
> простой фильтр, где можно менять добротность одним умножением, поделишься кодом?
Я уже, вроде бы, давал Q-фильтр, это он.
gammaker
> Такой простенький алгоритм подойдёт?
Это простой Delay, а №91 в GM - это Hall. Можешь взять мою реализацию, применял её в Cool:
Как я уже писал, в массиве ArSong() структура из трёх величин - L, R и Rev. Первую часть до этой строки:
For i = 0 To SizeSong - (LL - 1)
можно сделать однократно в начале, остальное, с виду, вполне переделывается под реалтайм.
И потом, после всего, хорошо бы выходной сигнал закомпрессировать, это избавит от проблем переполнения и добавит в звук "мяса", алгоритм проще, чем Hall, можно тоже взять из Cool.
Mikle
> Так быть не может. В сэмпле с длительностью X могут быть гармоники только с
> периодами, кратными X. То есть, например, в секундном сэмпле могут быть только
> целые частоты - 403 Гц или 188 Гц, но не 344.6. В двухсекундном могут быть уже
> половинки - 33.5 Гц, но не 33.75.
У меня частота дискретизации 48000 Гц, я заполняю массив с 32768 комплексными амплитудами, предполагая, что между соседними индексами у меня шаг 48000 / 2 / 32768 = 0,732421875 Гц. Прогоняю через IFFT, в итоге получаю периодический семпл размером 32768. Я сам не до конца понимаю, как это работает, ведь если бы я привёл все частоты к общему знаменателю, вместо 32768 получилось бы огромное число. Предполагаю, что это как-то получается из теоремы Котельникова, ведь она говорит, что для задания каждой частоты достаточно двух семплов.
Может как-нибудь потом разберусь, а пока работает и ладно. Если кто-нибудь здесь объяснит, вообще хорошо будет.
Mikle
> Нет, она поднимает уровень частот, более близких к резонансу (с любой стороны),
> ничего не опускает.
А всё, понял, мы не же про low pass фильтр, а про резонансный.Mikle
> Я уже, вроде бы, давал Q-фильтр, это он.
А, да, был какой-то FilterQ. Возьму его тогда.
Mikle
> Это простой Delay, а №91 в GM - это Hall. Можешь взять мою реализацию, применял
> её в Cool:
Спасибо, наверное её и возьму, раз в GM такое используется.
А на слух насколько большая разница? Твоя реализация выглядит в разы тяжелее. Если в MIDI используются все 16 каналов, то реалтайм может наверное не везде потянуть. Я так понимаю, магическое число 127 регулирует качество эффекта? Что будет если его уменьшать?
Хотя в любом случае для слабых устройств можно будет сделать fallback на обычный delay.
Можешь скинуть версию Cool без реверба? Хочу сравнить, насколько крутой эффект даёт сам реверб.
Mikle
> и добавит в звук "мяса"
В каком смысле? Разве компрессия не просто выравнивает громкости?
Только сегодня узнал чем CC120(All Sound Off) отличается от СС123(All Notes Off), в последнем оказывается пока педальку Sustain (СС64, СС66) не отжали все проигрываемые ноты которые под ее "эффектом" продолжают играть.
И еще один момент СС124-СС127 также дополнительно воспринимаются как All Notes Off.
http://nickfever.com/music/midi-cc-list
http://oktopus.hu/uploaded/Tudastar/MIDI%201.0%20Detailed%20Specification.pdf
gammaker
> У меня частота дискретизации 48000 Гц
Теперь понятно почему хай-хет выше звучит.
gammaker
> Если в MIDI используются все 16 каналов, то реалтайм может наверное не везде потянуть.
Так это же обработка микса собранных со всех каналов посылов на ревер, одна на все каналы.
gammaker
> магическое число 127 регулирует качество эффекта? Что будет если его уменьшать?
Точнее 128. Да, можно уменьшить, 64 ещё ничего, а 32 - уже будет "рассыпчатость", слышно на звуках с резкой атакой, типа акустической гитары, того же хай-хета.
gammaker
> Можешь скинуть версию Cool без реверба? Хочу сравнить, насколько крутой эффект
> даёт сам реверб.
Могу, но там я не сильно ревером увлекался, лучше пропишу специально что-нибудь с сильным ревером.
gammaker
> Разве компрессия не просто выравнивает громкости?
Точнее, сужает динамический диапазон, это воспринимается, как увеличение громкости при той же амплитуде, плюс повышается разборчивость.
Прописал:
Вот сэмпл гитары с ревером и без: https://yadi.sk/d/lA8R0YIx3RAdGg
Попробуй обработать сухой звук делэем в каком-нибудь редакторе - ничего хорошего не выйдет.
Aroch
> пока педальку Sustain (СС64, СС66)
Я даже не знаю, что это такое, пока дело до этого не дошло.
Mikle
> Теперь понятно почему хай-хет выше звучит.
А как это поправить, чтобы для 48000 генерировался семпл со звучанием как для 44100? От какого коэффициента это зависит? А то что-то не могу найти в этом коде никакого dt.
Mikle
> Вот сэмпл гитары с ревером и без: https://yadi.sk/d/lA8R0YIx3RAdGg
Спасибо, интересно.
Вопросы по фильтру:
Public Sub FilterQ(Ar( ) As Single, ByVal ArSz As Long, ByVal Frq As Single, ByVal Demp As Single) Dim p As Double Dim s As Double Dim F As Double Dim i As Long F = Frq / 7019 p = 0 s = 0 For i = 0 To ArSz - 1 p = p + s * F + Ar( i) s = ( s - p * F) * Demp Ar( i) = p Next i End Sub
Что здесь является добротностью (Demp?), в каком интервале изменяется, и с какой скоростью её нужно менять, чтобы после компенсации увеличения громкости получить экспоненциальное затухание высоких частот, как в Карплюс-Стронге?
gammaker
> А как это поправить, чтобы для 48000 генерировался семпл со звучанием как для
> 44100? От какого коэффициента это зависит? А то что-то не могу найти в этом
> коде никакого dt.
Попробуй немного уменьшить параметр Frc в PlateStart. Там непрямая зависимость, поэкспериментируй.
gammaker
> Что здесь является добротностью (Demp?), в каком интервале изменяется
Demp меняется от 0 до 1, при Demp=1 добротность бесконечная, чтобы она росла по экспоненте сделай как-то так:
Public Sub FilterQ(Ar() As Single, ByVal ArSz As Long, ByVal Frq As Single, ByVal Spd As Single) Dim p As Double Dim s As Double Dim F As Double Dim i As Long Dim D As Double F = Frq / 7019 p = 0 s = 0 D = 0.9 For i = 0 To ArSz - 1 p = p + s * F + Ar(i) s = (s - p * F) * (1 - D) Ar(i) = p D = D * Spd Next i End Sub
Spd - это скорость нарастания добротности, величина немного меньше единицы, скажем, 0.9999, подбери, мне сейчас не на чем проверить, пишу на вскидку.
И вместо 7019 будет другая величина, 7019 - это 44100/(2*Pi).
gammaker
> Я даже не знаю, что это такое, пока дело до этого не дошло.
Там два вида ее:
1) сс64, пока она нажата все клавиши которые были нажаты остаются нажатыми даже если их отпустили.
2) сс66, все клавиши которые были нажаты в момент когда зажата педаль так и остаются зажатыми пока не отпущена педаль, это позволяет продолжать дальше играть как обычно и удерживать ранее нажатые клавиши.
Mikle
> Demp меняется от 0 до 1, при Demp=1 добротность бесконечная, чтобы она росла по
> экспоненте сделай как-то так
Меня смущает, что даже при Demp=0 после фильтрации семпл содержит сумму всех предыдущих. При старте уже много высоких частот пропадает. Хотелось бы начинать с исходной формы волны, а не с размытой.
Правка:
Попробовал. Ничего похожего на гитару не получается. Как будто все гармоники кроме базовой исчезают одинаково быстро. Нота быстро превращается в синус, да и изначально ей не хватает высоких частот. Совсем не звучит как гитара.
Правка 2:
Я тут подумал, может просто взять low pass фильтр и плавно менять его cutoff frequency? Я у тебя видел FilterHP. Вопрос как его переделать, чтобы получить low pass и как считается коэффициент по частоте?
gammaker
> Я у тебя видел FilterHP
У того фильтра низкая крутизна, всего 6 дб/о, и изменить добротность, как в Q фильтре, нельзя, он точно не подойдёт.
gammaker
> изначально ей не хватает высоких частот
Это, скорее всего, можно исправить, но, боюсь, смысла нет из-за этой проблемы:
gammaker
> Как будто все гармоники кроме базовой исчезают одинаково быстро
Там скорость убывания ВЧ на частотах, значительно выше основной, растёт линейно, а не по экспоненте.
Mikle
> У того фильтра низкая крутизна, всего 6 дб/о, и изменить добротность, как в Q
> фильтре, нельзя, он точно не подойдёт.
Но если я буду уменьшать экспоненциально cutoff frequency, то верхние частоты будут от неё всё дальше и дальше от этого порога и соответственно быстрее экспоненциально затухать. Например, если я буду двигать cutoff frequency по октаве в секунду, высокие частоты будут затухать со скоростью 6 дБ\с. Правда неизвестно, с какой частоты начинать, чтобы эффект был заметен сразу же, а не пока пороговая частота опустится ниже определённого уровня. Наверное в этом будет основная проблема.
А больше никаких подходящих фильтров нет? Как вообще обычно добиваются постепенного затухания высоких частот в субтрактивном синтезе кроме обычного Карплюс-Стронга?
Или может как-нибудь всё-таки можно модифицировать Карплюса-Стронга, чтобы он работал с произвольными периодами любой длины, не привязанной к частоте? Я хочу руками через FFT создавать сложные спектры, и заставить их эволюционировать, а не просто периодически повторяться, как у меня сейчас. По идее с такими длинными периодами усреднение в KS будет очень редко происходить - по времени порядка раз в полсекунды. А так как оно только соседние семплы затрагивает, это не даст практически никакого эффекта.
Mikle
Реализовал реверберацию. С твоими параметрами большинстве мелодий амплитуда выходит за границы, происходит нормализация и всё начинает играть очень тихо. И время синтеза увеличилось в 5 раз. На моём ноутбучном Core i7 реверберация быстрее реалтайма всего в 30 раз. Если запускать на слабых устройствах, это может быть впритык. Хотелось бы побыстрее, но я не вижу способа это оптимизировать дальше. На SIMD это не ложится и распараллелить на несколько ядер вроде тоже нельзя.
Попробовал уменьшить количество задержек до 32, нормировав сумму Vol на то же самое число. Эффект стал намного сильнее, пришлось поэтому я уменьшил все Vol в 5 раз. Стало гораздо слабее вылезать за диапазон. Уже лучше и работает в 4 раза быстрее. Но всё равно по времени ощутимо замедляет синтезатор и смущает отсутствие потенциала для оптимизации. Может есть что побыстрее с приемлемым качеством?
Кстати, а в виндовом синтезаторе используется реверберация? А то я её как-то ни разу не слышал.
Тема в архиве.