Pregunta

Estoy escribiendo un sintetizador de software y necesito generar formas de onda sin alias, sin límite de banda, en tiempo real a una velocidad de muestreo de 44.1 kHz. La forma de onda de diente de sierra haría por ahora, ya que puedo generar una onda de pulso mezclando dos dientes de sierra juntos, uno invertido y desfasado.

Hasta ahora he probado los siguientes métodos:

  1. Al precomputar muestras de forma de onda con un límite de banda perfectamente en diferentes frecuencias de límite de banda al inicio, luego se reproducen las dos más cercanas mezcladas. Funciona bien, supongo, pero no se siente muy elegante. Se necesitan muchas muestras o las " brechas " entre ellos se oirá. La interpolación y la mezcla también requieren bastante CPU.

  2. La integración de un tren de CD compensó los pulsos sinc para obtener una onda de diente de sierra. Suena muy bien, excepto que la ola se aleja de cero si no obtiene la compensación de CC exactamente correcta (lo que me pareció realmente complicado). El problema de CC se puede reducir agregando un poco de fuga al integrador, pero luego se pierden 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.

¿Fue útil?

Solución

Hay muchas formas de acercarse a la generación de forma de onda con límite de banda. Terminará negociando el costo computacional con la calidad como de costumbre.

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

http://www.musicdsp.org/

Revisa el archivo! Está lleno de buen material. Acabo de hacer una búsqueda en la palabra clave " límite de banda " ;. El material que aparece debe mantenerse ocupado durante al menos una semana.

Btw: no sé si eso es lo que está buscando, pero hice un alias reducido (por ejemplo, no muy limitado por la banda) generación de forma de onda hace un par de años. Acabo de calcular la integral entre la última posición de muestra y la actual. Para las formas de onda de sintetizador tradicionales, puede hacerlo con bastante facilidad si divide su intervalo de integración en las singularidades (por ejemplo, cuando el diente de sierra se reinicia). La carga de la CPU fue baja y la calidad aceptable para mis necesidades.

Tuve los mismos problemas de deriva, pero al aplicar un paso alto con una frecuencia de corte muy baja en la integral se eliminó ese efecto. El sintetizador analógico real no baja a la región de subhertz de todos modos, por lo que no te perderás mucho.

Otros consejos

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

ingrese la descripción de la imagen aquí

y guárdelo en una tabla de ondas, luego reemplace cada transición con un paso de banda limitada, para crear formas de onda que se parecen a esto:

ingrese la descripción de la imagen aquí

Consulte el tutorial en Síntesis de sonido de banda limitada .

Dado que este BLEP no es causal (lo que significa que se extiende hacia el futuro), para generar formas de onda en tiempo real, es mejor usar el paso de banda mínima de fase limitada, denominado a MinBLEP , que tiene el mismo espectro de frecuencias, pero solo se extiende hasta el pasado:

  

Los minBLEPs llevan la idea más lejos y   tomar una ventana sinc, realizar una   Reconstrucción de fase mínima y luego   integrar el resultado y almacenarlo en una   mesa. Ahora para hacerte un oscilador   solo inserta un MinBLEP en cada   discontinuidad en la forma de onda. Entonces para   una ola cuadrada inserta un MinBLEP   Donde se invierte la forma de onda, para sierra.   ola inserta un MinBLEP donde el   el valor se invierte, pero se genera el   rampa como normal.

Esto es lo que se me ocurrió, inspirado en las ideas de Nils. Pegándolo aquí en caso de que sea útil para otra persona. Simplemente, filtre de forma analítica una onda de diente de sierra utilizando el cambio de fase de la última muestra como tamaño de núcleo (o corte). Funciona bastante bien, hay algunos alias audibles en las notas más altas, pero para el uso normal suena muy bien.

Para reducir aún más el alias, el tamaño del kernel se puede aumentar un poco, por lo que 2 * phaseChange también suena bien, aunque pierdes un poco las frecuencias más altas.

También, aquí hay otro buen recurso DSP que encontré al buscar en el SP temas similares: El Kit de herramientas de síntesis en C ++ (STK) . Es una biblioteca de clases que tiene muchas herramientas DSP útiles. Incluso tiene listos para usar generadores de forma de onda de banda limitada. El método que utilizan es integrar sinc como describí en mi primera publicación (aunque creo 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);
}

¡El offset de CC de una blit se puede reducir con un simple filtro de paso alto! - ¡Al igual que un circuito analógico real en el que usan una tapa de bloqueo de CC!

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top