2008-10-06 11 views
10

Estoy escribiendo un sintetizador de software y necesidad de generar formas de onda de banda limitada, alias libres en tiempo real de muestreo a 44,1 kHz. Por ahora, la forma de onda del diente de sierra funcionaría, ya que puedo generar una onda de pulso al mezclar dos dientes de sierra, uno invertido y otro con fase.banda limitada generación de forma de onda

Hasta ahora he tratado los siguientes enfoques:

  1. precomputación de muestras de forma de onda de un ciclo perfectamente a diferentes frecuencias de banda limitada Bandlimit en el arranque, a continuación, la reproducción de las dos más cercanas mezclados entre sí. Funciona bien, supongo, pero no se siente muy elegante. Se necesitan muchas muestras o se escucharán las "brechas" entre ellas. La interpolación y la mezcla también consumen mucha CPU.

  2. La integración de un tren de pulsos de CC compensada sinc para obtener una onda de diente de sierra. Suena genial, excepto que la ola se aleja de cero si no obtienes la compensación de CC exactamente correcta (lo cual me pareció realmente complicado). El problema de CC se puede reducir agregando un poco de fuga al integrador, pero luego pierde las bajas frecuencias.

Entonces, mi pregunta es: ¿Cuál es la forma habitual de hacerlo? Cualquier solución sugerida debe ser eficiente en términos de CPU, ya que debe hacerse en tiempo real, para muchas voces a la vez.

+0

Me doy cuenta de que esto fue preguntado hace aproximadamente un año, pero para cualquier persona que se tropiece con esto, le recomendaré buscar el amigable y altamente competente [DSP y Plug-in Development] (http://www.kvraudio.com/ foro/viewforum.php? f = 33) foro en [KVR] (http://www.kvraudio.com/) –

Respuesta

4

Hay muchas maneras de acercarse a la generación de forma de onda de banda limitada. Terminará intercambiando el costo computacional con la calidad como de costumbre.

le sugiero que eche un vistazo a este sitio aquí:

http://www.musicdsp.org/

Salida el archivo! Está lleno de buen material. Acabo de hacer una búsqueda sobre la palabra clave "bandlimited". El material que aparece debe mantenerse ocupado durante al menos una semana.

BTW - No sabe si eso es lo que busca, pero yo no reduce alias (por ejemplo, no es realmente una limitación de banda) de generación de forma de onda hace un par de años. Acabo de calcular la integral entre la última y actual posición de muestra. Para las formas de onda de sintetizador tradicionales, puede hacerlo bastante fácil si divide el intervalo de integración en las singularidades (por ejemplo, cuando el diente de sierra obtiene su restablecimiento). La carga de la CPU era baja y la calidad aceptable para mis necesidades.

que tenían los mismos problemas de deriva, pero la aplicación de un paso alto con una muy baja frecuencia de corte de la integral se deshizo de ese efecto. Los sintetizadores analógicos reales no bajan a la región de subhertz de todos modos, por lo que no se perderá demasiado.

+0

"phase + = (sampleRate/(float TableSize)/frequency;" no se compila. "(sampleRate/(float TableSize))/frequency;"? – user877329

+0

¡Buen enlace! Lleno de montones de pequeños y agradables fragmentos – SvaLopLop

2

Esto es lo que me ocurrió, inspirado en las ideas de Nils. Pegarlo aquí en caso de que sea útil para otra persona. Simplemente recuadro filtrar una onda de diente de sierra analíticamente usando el cambio de fase de la última muestra como tamaño de núcleo (o punto de corte). Funciona bastante bien, hay un alias audible en las notas más altas, pero para el uso normal suena genial.

Para reducir aún más el aliasing, el tamaño del kernel puede aumentarse un poco, por lo que es 2 * phaseChange, por ejemplo, también suena bien, aunque se pierde un poco de las frecuencias más altas.

Además, aquí es otro buen recurso DSP he encontrado al navegar SP para temas similares: The Synthesis ToolKit in C++ (STK). Es una biblioteca de clases que tiene muchas herramientas DSP útiles. Incluso tiene generadores de forma de onda limitados a la banda listos para usar. El método que usan es para integrar el sinc como lo describí en mi primera publicación (aunque supongo que lo hacen mejor que yo ...).

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

Una forma rápida de generar formas de onda de banda limitada es mediante el uso de pasos de banda limitada (BLEP). Se genera el paso de banda limitada en sí:

enter image description here

y almacenar que en una tabla de ondas, a continuación, sustituya cada transición con un paso de banda limitada, para crear formas de onda que se ven así:

enter image description here

Consulte el recorrido en Band-Limited Sound Synthesis.

Dado que este BLEP no es causal (es decir, se extiende hacia el futuro), para generar formas de onda en tiempo real, es mejor utilizar el paso de banda mínima de fase limitada, llamado MinBLEP, que tiene el mismo espectro de frecuencia , pero sólo se extiende hacia el pasado:

MinBLEPs dar a la idea y toman una función sinc con ventana, lleve a cabo una reconstrucción fase mínima y luego integrar el resultado y lo almacenan en una tabla . Ahora para hacer un oscilador usted simplemente inserte un MinBLEP en cada discontinuidad en la forma de onda. Entonces para una onda cuadrada inserta un MinBLEP donde la forma de onda se invierte, para sierra onda inserta un MinBLEP donde el valor se invierte, pero genera la rampa de forma normal.

1

La compensación de CC de una blit: se puede reducir con un simple filtro de paso alto. - ¡muy parecido a un circuito analógico real donde usan una tapa de bloqueo de CC!

Cuestiones relacionadas