> А как я понял по небольшому гуглингу VST и есть семплы?
Нет, VST это программная спецификация на модули обработки и синтеза звука, а также на программы, использующие такием модули. Проще говоря, это такой стандарт для DLL (ну или других видов динамических библиотек, если не под виндами), указывающий какие в ней должны быть функции, что они должны принимать, и что отдавать.
Соответственно, синтезирующие модули могут генерить звук (точнее, возвращаемый в очередном вызове кусок волны) как с семплами, так и просто чистой математикой.
Dmitry_Milk
То есть их поддержку добавить к себе элементарно, всего-то LoadLibrary и несколько GetProcAddress? И можно юзать кучу накопившихся библиотек? Интересно, но я предпочитаю собирать всё статически в одном файле, адаптируя их напрямую к своему коду. Ведь эти плагины в основном идут с открытыми исходниками?
Но для сторонних пользователей синтезатора можно добавить поддержку подключения таких dll.
gammaker
> Там есть параметр, pitch bend называется. Можно ли этот способ адаптировать для
> неё? Я так понимаю, что переменный шаг всё поломает и синус разойдётся?
Не разъедется. Просто меняешь текущий шаг (приращение фазы) и все. Сама фаза едет как и ехала всегда вперед.
> А как я понял по небольшому гуглингу VST и есть семплы?
Нет же, это формат плагинов.
gammaker
> То есть их поддержку добавить к себе элементарно, всего-то LoadLibrary и
> несколько GetProcAddress?
Нет, хост грузит твой плагин сам. Ты делаешь в DLL по стандарту VST функцию в DLL и реализуешь интерфейсы, которые ему необходимы.
d.m.k
> Не разъедется. Просто меняешь текущий шаг (приращение фазы) и все. Сама фаза
> едет как и ехала всегда вперед.
Но ведь для этого нужно синус или косинус пересчитать? А если приращение фазы непрерывно меняется, то придётся каждый семпл косинус считать и никакого толку от оптимизации тогда не будет?
d.m.k
> Нет же, это формат плагинов.
Да мне уже объяснили.
d.m.k
> Нет, хост грузит твой плагин сам. Ты делаешь в DLL по стандарту VST функцию в
> DLL и реализуешь интерфейсы, которые ему необходимы.
Ну я считаю наоборот, что я делаю хост, а не плагины и юзаю уже тысячи готовых плагинов.
Epsilon
Я послушал твой ft2 и не услышал щелчков.
Посмотрел синусоиду звука на Audacity и там тоже сигнал нормальный без рывков и лишнего шума.
Вроде все ок.
> Нет, хост грузит твой плагин сам. Ты делаешь в DLL по стандарту VST функцию в DLL и реализуешь интерфейсы, которые ему необходимы.
Можно и наоборот делать. В штейнбергском SDK есть примеры как плагинов, так и наоборот, простого хоста. gammaker правильно понял мою мысль.
> Но ведь для этого нужно синус или косинус пересчитать? А если приращение фазы непрерывно меняется, то придётся каждый семпл косинус считать
> и никакого толку от оптимизации тогда не будет?
Если рассматривать случай, когда приращение фазы меняется равномерно, то к паре синус/косинус приращения фазы можно применить те же самые тригонометрические формулы, как и для пары синус/косинус самой фазы. Ведь приращение фазы - тоже угол поворота, как и сама фаза ;)
События PitchBend приходят достаточно редко, в эти моменты можно по-настоящему высчитать требуемую пару синус/косинус (тут на помощь приходит тот факт, что внутри функций sin и cos они часто считаются через одни и те же компоненты, и поэтому практически всегда наряду с sin и cos есть функция, выдающая сразу пару (sin,cos) ). Ну а между событиями линейно интерполировать вышепредложенным способом.
Зачем вообще синус косинус? Бегай кругами по предвычесленному единожды одному участку синусоиды (0..2*pi), меняя только частоту но не фазу, и всё.
Не надо трогать фазы. Рендеришь буфер когда, просто время прихода события Pitch bend учитывай, и всё.
Dexus
> Зачем вообще синус косинус? Бегай кругами по предвычесленному единожды одному
> участку синусоиды (0..2*pi), меняя только частоту но не фазу, и всё.
Тогда интерполировать придётся, потому что индекс не будет попадать точно в массив. И переводить float индексы в int, что наверное даже дольше вычисления синуса. Хотя можно конечно через фиксированную точку фазу считать.
А может быть конечно и так прокатит без интерполяции, если массив побольше взять...
> Бегай кругами по предвычесленному единожды одному участку синусоиды (0..2*pi)
1). Невозможно задействовать SIMD
2). Используется узкое место проца, не очень удобное для суперскалярных "out of order" процов - модуль доступа к памяти (пусть даже полностью помещающейся в кэш проца). Косвенное обращение к памяти (через указатель, вычисляемый не через сложение с константой) - хреновая ситуация для этого модуля, в данном случае еще и отягощенная тем, что нет даже постоянного страйда (шага доступа), т.к. иногда в целую часть приращения указателя добавляется перенос из дробной части (которую тоже надо накапливать, если хочешь получить частоты с достаточной для музыки точностью). То есть, предсказатель адресов обращения в данном случае сливает по полной программе, приводя к большому числу неудачных спекулятивных вычислений.
В итоге метод через предвычисленную синусоиду в десяток, а то и более раз проигрывает методу синтеза через поворот фазы. Проверено уже не одним человеком.
Ну и еще в добавок:
3). Из-за некратного шага сканирования нужен как минимум антиалиасинг хотя бы в виде линейной интерполяции от накапливаемой дробной части, иначе получишь паразитные гармоники, причем некратные базовой частоте, что будет весьма заметно людям с хорошей акустикой и слухом.
> Не надо трогать фазы
Фазой выше называется положение внутри периода синусоиды. Считай, "индекс в буфере" предпросчитанного синуса.
gammaker
> Тогда интерполировать придётся, потому что индекс не будет попадать точно в массив.
Зачем интерполировать? В крайнем случае округлить. 44100 выборок для 44100Гц достаточно.
Dmitry_Milk
> 1). Невозможно задействовать SIMD
И зачем они?
> В итоге метод через предвычисленную синусоиду в десяток, а то и более раз проигрывает методу синтеза через поворот фазы.
Прошу предоставить результаты тестов с десятикратной разницей.
> 3). Из-за некратного шага сканирования нужен как минимум антиалиасинг хотя бы в виде линейной интерполяции от накапливаемой дробной части, иначе получишь паразитные гармоники, причем некратные базовой частоте, что будет весьма заметно людям с хорошей акустикой и слухом.
Уже проверяли?
У меня под рукой OPL2 эмулятор (который работает без антиалиасинга, на fixedpoint), и на фоне самого качества FM синтеза никаких "паразитных" гармоник я не слышу, хотя занимаюсь звуком уже лет 20. Паразитные гармоники начинают вылазить когда используешь частоты выше 4КГц. А это не совсем уже музыкальный диапазон, и "паразитные" от "не паразитных" не отличишь, если это конечно не банальная пила или синусоида.
> И зачем они?
Если незачем, тогда и второй вопрос смысла не имеет, раз отъедаемый процессор не беспокоит.
> Прошу предоставить результаты тестов с десятикратной разницей.
Лень раскапывать. Дело было лет 7-8 назад. Баловался аддитивным синтезом а-ля АНС, надо было порядка семи сотен взвешенно суммированных синусоид в риалтайм 44100. Первая версия была именно с таблицей предпросчитанного синуса и сканированием с фиксированной точкой. Проц (тогда пень III 1ГГц) тянул на грани, на гуи не хватало, все щелкало. Стал искать другие методы, узнал про SSE, решил распараллелить, надеясь, что раза в 2-3 хотя бы ускорю. Выяснив, что SSE плохо скрещивается с косвенным обращением к памяти, стал думать про другие методы, набрел на поворот фазы. В совокупности с SSE результат очень удивил - быстродействие увеличилось раз в 9-10 (замерял через время выполнения нереалтаймового рендеринга заданного количества отсчетов).
>Уже проверяли?
Нет. Но следуя логике, они должны быть, и могут быть в очень неконсонансных соотношениях с частотой синтезируемого синуса.
Dmitry_Milk
>Если рассматривать случай, когда приращение фазы меняется равномерно, то к паре синус/косинус приращения фазы можно применить те же самые тригонометрические формулы, как и для пары синус/косинус самой фазы. Ведь приращение фазы - тоже угол поворота, как и сама фаза ;)
Вот аккуратнее с такими утверждениями, а?
Если это в лоб сделать, то второе приращение получится (типично) крохотным, и вся эта радость может разъехаться на float (экспоненциальное возрастание амплитуды). Если знаешь как сделать нормально - так делись, что-ли...
> Если это в лоб сделать, то второе приращение получится (типично) крохотным, и вся эта радость может разъехаться на float
Блин, логично, не учел :) Но вообще метод (пусть слегка жульнический) борьбы с экспоненциальным возрастанием я уже выше давал - постоянный контроль/коррекция значений, чтоб не вылезали за единицу (max/maxps значения с единицей(ами), чтоб без сравнений и условных переходов). С учетом того что за один период много набежать не успеет, коррекция практически не должна сказываться на качестве синусоиды. Правда к приращению эту коррекцию уже применить не получится, только непосредственно к синтезируемой синусоиде.
Ну а при очередном питчбенд-событии снова расчитать синус/косинус приращения по-честному.
Тема в архиве.