2008-10-06 5 views
10

Я пишу программный синтезатор и вам необходимо генерировать полосы без полей, в виде свободных сигналов в реальном времени с частотой 44,1 кГц. Звуковая форма пилот-сигнала будет делать сейчас, так как я могу генерировать импульсную волну, смешивая два пилообразных пилы вместе, один перевернутый и сдвинутый по фазе.Генерация волны с обводненностью по диапазону

До сих пор я попытался следующие подходы:

  1. Предвычисление один цикл отлично с ограниченной полосой выборок формы сигнала на разных частотах bandlimit при запуске, то воспроизведение двух самых близких из них смешаны вместе. Работы хорошо, я думаю, но не чувствую себя очень элегантно. Требуется много образцов, или будут слышны «промежутки» между ними. Интерполяция и микширование также достаточно интенсивны.

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

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

+0

Я понимаю, что это было спрошено около года назад, но для кого-то еще наткнувшись на это, я порекомендую найти дружелюбный и высококвалифицированный [DSP и Plug-in Development] (http://www.kvraudio.com/ forum/viewforum.php? f = 33) форум в [KVR] (http://www.kvraudio.com/) – 2009-10-03 07:15:43

ответ

4

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

Я предлагаю вам взглянуть на этот сайт здесь:

http://www.musicdsp.org/

Заканчивать архив! Он полон хорошего материала. Я просто выполнил поиск по ключевому слову «bandlimited». Материал, который появляется, должен оставаться занятым хотя бы на неделю.

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

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

+0

«фаза + = (sampleRate/(float TableSize)/frequency;» не компилируется. "(sampleRate/(float TableSize))/frequency;"? – user877329 2014-07-06 17:17:15

2

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

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

Кроме того, вот еще один хороший ресурс DSP, который я нашел при просмотре SP для похожих тем: The Synthesis ToolKit in C++ (STK). Это библиотека классов, в которой есть много полезных инструментов DSP. Он даже готов использовать генераторы генераторов с полосой пропускания. Метод, который они используют, - это интегрировать sinc, как я описал в своем первом посте (хотя, я думаю, они делают это лучше меня ...).

float getSaw(float phaseChange) 
{ 
    static float phase = 0.0f; 
    phase = fmod(phase + phaseChange, 1.0f); 
    return getBoxFilteredSaw(phase, phaseChange); 
} 

float getPulse(float phaseChange, float pulseWidth) 
{ 
    static float phase = 0.0f; 
    phase = fmod(phase + phaseChange, 1.0f); 
    return getBoxFilteredSaw(phase, phaseChange) - getBoxFilteredSaw(fmod(phase + pulseWidth, 1.0f), phaseChange); 
} 

float getBoxFilteredSaw(float phase, float kernelSize) 
{ 
    float a, b; 

    // Check if kernel is longer that one cycle 
    if (kernelSize >= 1.0f) { 
     return 0.0f; 
    } 

    // Remap phase and kernelSize from [0.0, 1.0] to [-1.0, 1.0] 
    kernelSize *= 2.0f; 
    phase = phase * 2.0f - 1.0f; 

    if (phase + kernelSize > 1.0f) 
    { 
     // Kernel wraps around edge of [-1.0, 1.0] 
     a = phase; 
     b = phase + kernelSize - 2.0f; 
    } 
    else 
    { 
     // Kernel fits nicely in [-1.0, 1.0] 
     a = phase; 
     b = phase + kernelSize; 
    } 

    // Integrate and divide with kernelSize 
    return (b * b - a * a)/(2.0f * kernelSize); 
} 
6

Одним быстрым способом генерации сигналов с ограничением по диапазону является использование ограниченных полосами шагов (BLEPs). Вы генерировать полосовой ограниченный шаг сам:

enter image description here

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

enter image description here

См. Прохождение по адресу Band-Limited Sound Synthesis.

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

MinBLEPs принять идею дальше и взять оконный Sinc, выполнить реконструкцию с минимальной фазы, а затем интегрировать результат и сохранить его в таблицы. Теперь, чтобы создать осциллятор, вы должны вставить MinBLEP при каждом разрыве в форме волны. Итак, для квадратной волной вы вставляете MinBLEP , где волновая форма инвертируется, для пилы волна вы вставляете MinBLEP, где значение инвертируется, но вы генерируете рампу как обычно.

1

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

 Смежные вопросы

  • Нет связанных вопросов^_^