2008-10-06 5 views
10

J'écris un synthétiseur logiciel et j'ai besoin de générer des formes d'onde sans alias, limitées en bande, en temps réel à 44,1 kHz. La forme d'onde en dent de scie ferait pour l'instant, puisque je peux générer une onde de pouls en mélangeant deux dents de scie ensemble, une inversée et déphasée.Génération de formes d'ondes avec limitation de fréquence

Jusqu'à présent, j'ai essayé les approches suivantes:

  1. précalcul un cycle d'échantillons de forme d'onde parfaitement à différentes fréquences à bande limitée de bandlimit au démarrage, puis la lecture des deux plus proches mélangés. Ça marche, je suppose, mais ça ne me semble pas très élégant. Beaucoup d'échantillons sont nécessaires ou les «trous» entre eux seront entendus. L'interpolation et le mélange sont également très sollicités par le processeur.

  2. Intégration d'un train d'impulsions sinc compensées en courant continu pour obtenir une onde en dents de scie. Cela sonne bien sauf que la vague dérive de zéro si vous n'obtenez pas exactement la compensation DC (ce que j'ai trouvé très difficile). Le problème de CC peut être réduit en ajoutant un peu de fuite à l'intégrateur, mais alors vous perdez les basses fréquences.

Alors, ma question est: Quelle est la façon habituelle de faire cela? Toute solution proposée doit être efficace en termes de CPU, car elle doit être faite en temps réel, pour plusieurs voix à la fois.

+0

Je me rends compte que cela a été demandé il y a un an, mais pour quelqu'un d'autre qui trébuche sur ce point, je vais recommander la recherche amicale et hautement compétente [DSP et Plug-in Development] (http://www.kvraudio.com/ forum/viewforum.php? f = 33) forum à [KVR] (http://www.kvraudio.com/) –

Répondre

4

Il existe de nombreuses façons d'approcher la génération de formes d'ondes avec limitation de bande. Vous finirez par échanger des coûts de calcul contre la qualité comme d'habitude.

Je vous suggère de jeter un oeil sur ce site ici:

http://www.musicdsp.org/

Découvrez l'archive! C'est plein de bon matériel. Je viens de faire une recherche sur le mot-clé "bandlimited". Le matériel qui apparaît devrait vous occuper pendant au moins une semaine. Btw - Je ne sais pas si c'est ce que vous cherchez, mais j'ai fait une génération de forme d'onde alias réduite (par exemple pas vraiment limitée en bande) il y a quelques années. Je viens de calculer l'intégrale entre la dernière et la position actuelle de l'échantillon. Pour les formes d'onde de synthé traditionnelles, vous pouvez le faire assez facilement si vous divisez votre intervalle d'intégration en singularités (par exemple lorsque la dent de scie est réinitialisée). La charge du processeur était faible et la qualité acceptable pour mes besoins.

J'ai eu les mêmes problèmes de dérive, mais en appliquant un passe-haut avec une fréquence de coupure très faible sur l'intégrale on s'est débarrassé de cet effet. Le vrai synthé analogique ne descend pas dans la région subhertz de toute façon, donc vous ne manquerez pas beaucoup.

+0

"phase + = (sampleRate/(float TableSize)/frequency;" ne compile pas. "(sampleRate/(float TableSize))/fréquence;"? – user877329

+0

Bon lien! Plein de charges de bons petits extraits – SvaLopLop

2

C'est ce que j'ai trouvé, inspiré par les idées de Nils. Coller ici au cas où il serait utile pour quelqu'un d'autre. Je filtre simplement une onde en dents de scie analytiquement en utilisant le changement de phase du dernier échantillon comme taille de noyau (ou de coupure). Cela fonctionne assez bien, il y a un aliasing audible aux notes les plus hautes, mais pour un usage normal ça sonne bien.

Pour réduire encore plus l'aliasing, la taille du noyau peut être augmentée un peu, ce qui fait que 2 * phaseChange par exemple sonne bien, même si vous perdez un peu des fréquences les plus hautes.

En outre, voici une autre bonne ressource DSP que j'ai trouvé lors de la navigation SP pour des sujets similaires: The Synthesis ToolKit in C++ (STK). C'est une bibliothèque de classe qui a beaucoup d'outils DSP utiles. Il a même prêt à utiliser des générateurs de formes d'ondes à bande limitée. La méthode qu'ils utilisent est d'intégrer sinc comme je l'ai décrit dans mon premier post (même si je suppose qu'ils le font mieux que moi ...).

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

Une façon rapide de générer des formes d'ondes à bande limitée est à l'aide d'étapes à bande limitée (BLEPs). Vous générez l'étape bande limitée elle-même:

enter image description here

et stocker que dans un wavetable, puis remplacer chaque transition d'une étape à bande limitée, pour créer des formes d'ondes qui ressemblent à ceci:

enter image description here

Voir le parcours au Band-Limited Sound Synthesis. Puisque ce BLEP est non causal (c'est-à-dire qu'il s'étend dans le futur), pour générer des formes d'onde en temps réel, il est préférable d'utiliser l'étape MinBLEP à bande limitée, qui a le même spectre de fréquence , mais seulement se prolonge dans le passé:

MinBLEPs prendre l'idée plus loin et prendre un sinc fenêtré, effectuer une reconstruction de phase minimale puis le résultat et intégrer le stocker dans une table . Maintenant pour faire un oscillateur vous suffit d'insérer un MinBLEP à chaque discontinuité dans la forme d'onde. Donc pour une onde carrée vous insérez un MinBLEP où la forme d'onde s'inverse, pour la scie vous insérez un MinBLEP où la valeur s'inverse, mais vous générez la rampe comme d'habitude.

1

Le décalage DC d'un blit - peut être réduit avec un simple filtre passe-haut! - un peu comme un vrai circuit analogique où ils utilisent un bouchon de blocage DC!

Questions connexes