2009-09-08 5 views
3

Je suis en train d'essayer de faire un logiciel qui fait fonctionner le clavier comme un piano (par exemple, l'utilisateur appuie sur la touche «W» et les haut-parleurs jouent une note D). J'utiliserai probablement OpenAL. Je comprends les bases de l'audio numérique, mais jouer de l'audio en temps réel en réponse à des pressions sur les touches pose certains problèmes que je n'arrive pas à résoudre.Créer une application audio en temps réel avec des synthétiseurs logiciels

Voici le problème: Supposons que je dispose de 10 tampons audio et que chaque tampon contient une seconde de données audio. Si je dois remplir des tampons avant qu'ils ne soient lus par les haut-parleurs, alors je remplirais les tampons une ou deux secondes avant qu'ils ne soient joués. Cela signifie que chaque fois que l'utilisateur essaie de jouer une note, il y aura un délai d'une ou deux secondes entre la pression de la touche et la note jouée.

Comment contournez-vous ce problème? Est-ce que vous faites juste les tampons aussi petits que possible, et les remplissez le plus tard possible? Y a-t-il un truc qui me manque?

Répondre

6

La plupart des synthétiseurs logiciels n'utilisent pas du tout de tampons multiples.

Ils utilisent juste un seul petit ringbuffer qui est constamment joué. Un thread haute priorité vérifie le plus souvent possible la position de lecture actuelle et remplit la partie libre (par exemple, la partie jouée depuis la dernière exécution de votre thread) du tampon de mémoire avec des données audio. Cela vous donnera une latence constante qui n'est limitée que par la taille de votre buffer d'anneau et la latence de sortie de votre carte son (en général, pas beaucoup).

Vous pouvez réduire votre temps d'attente encore plus loin:

En cas d'une nouvelle note à jouer (par exemple, l'utilisateur vient d'appuyer sur une touche) vous vérifiez la position de lecture actuelle dans la mémoire tampon en anneau, ajouter quelques échantillons pour la sécurité, puis re-rendre les données sonores avec les nouveaux paramètres sonores appliqués.

Cela devient difficile si vous avez des effets basés sur le temps (lignes à retard, réverbération, etc.), mais c'est faisable. Gardez une trace des 10 derniers états de vos effets basés sur le temps toutes les millisecondes environ. Cela permettra de revenir 10 millisecondes à temps.

+0

Cela a du sens. Pouvez-vous recommander des bibliothèques audio qui seraient bonnes pour cette approche de tampon unique? –

+0

Oui. Sur Win32 c'est direct. Simle comme ça. Pour Linux je ne sais pas vraiment. Très probablement ALSA. Pour une solution purement matérielle (par exemple une chose embarquée) vous ne voulez pas du tout d'API mais vous voulez que votre routine soit appelée depuis un gestionnaire d'interruptions. –

+0

Il n'est vraiment pas vrai que la plupart des synthétiseurs utilisent des tampons annulaires - VST et AudioUnits (donc, environ 90% du marché entre eux) utilisent l'approche multi-tampon avec de petits tampons. ALSA ne fournit pas d'équivalent du graphe de signaux DirectShow/Sound ou CoreAudio, mais il existe une abondance d'implémentations open source concurrentes. Quand il s'agit d'API pour soft-synthns en open-source, il a tendance à être VST tout le temps, en s'appuyant généralement sur la capacité de Linux de charger des fichiers exécutables Windows. – marko

1

Avec le WinAPI, vous pouvez seulement obtenir jusqu'à présent en termes de latence. Habituellement, vous ne pouvez pas descendre en dessous de 40-50 ms ce qui est assez désagréable. La solution consiste à implémenter le support ASIO dans votre application et à faire en sorte que l'utilisateur lance quelque chose comme Asio4All en arrière-plan. Cela ramène la latence à 5ms mais à un coût: les autres applications ne peuvent pas jouer du son en même temps. Je le sais parce que je suis un utilisateur FL Studio.

0

La solution est de petits tampons, remplis fréquemment par un thread en temps réel. La petite taille des tampons (ou la taille maximale que vous laissez au tampon avec un tampon circulaire) est limitée par la planification de la latence de votre système d'exploitation. Vous trouverez probablement 10ms pour être acceptable.

Il y a quelques pièges désagréables ici pour les non-initiés - en particulier en ce qui concerne l'architecture logicielle et la sécurité des threads.

Vous pouvez essayer de regarder Juce - qui est un cadre multi-plateforme pour l'écriture de logiciels audio, et en particulier - les plugins audio tels que SoftSynths et effets. Il inclut un logiciel pour les plug-ins d'échantillons et les hôtes. C'est dans l'hôte que les problèmes de threading sont principalement traités.

Questions connexes