Traitement du signal jack multichannel, délai constant...
Bonjour à tous !
Je suis ici car j'utilise Jack pour effectuer du filtrage actif a partir de mon pc, et je manque cruellement d'informations quant à la synchronisation temporelle des flux audio de jack...
Je vais donc poser quelques questions primaires dont vous aurez, étant développeurs, certainement la réponse :
1- comment est déterminée la latence du serveur jack ? Je m'explique : jack a une latence fixe indiquée que Qjackctl qui est apparemment du nombres de frames / period * nombres de périodes/fréquence de sampling.
frames = samples
frames/period*period = buffer ?
Je ne comprend pas très bien comment est assuré cette latence. Je m'explique :
Si j'ai le schéma suivant dans les connections jack:
appli_1-out ==> appli_2-in
appli_2-out ==> system:output
Est-ce que le temps de latence est le temps de latence annoncé sur l'interface Qjackctl ou 2x le temps de latence ? (puisque le signal fais 2 fois le chemin avant de sortir par la carte son ?)
2- J'utilise les plugins LADSPA pour appliquer des filtres passe-bas/passe-haut sur plusieurs canaux de mon système. Ces plugins sont hostées par des threads jack-rack. J'ai des problèmes quant à la synchronisation des delais des canaux. Je m'explique encore, par exemple j'ai ceci :
canal 1 ==> jack-rack-lowpass ==> system:out1
canal 2 ==> jack-rack-highpass ==> system:out2
Dans le thread jack-rack-lowpass j'ai divers plugins : un filtre IIR lowpass, un simple_amplifier, et admettons plusieurs simples bandes paramétriques (nombre indéterminé).
Lorsque j'effectue des mesues de mon système, le délai en samples des réponses d'impulsions des 2 voies ne sont pas constants. Je suis donc obligé d'appliquer un delai sur 1 canal pour scinder les 2 impulsions, repérer leur décalage, et calculer le décalage réel sans le délai que j'ajoute. Ainsi, en supprimant le délai, j'ai normalement les 2 impulsions des voies "grave" et "aigu" qui se superposent en phase. Le problème est qu'a chaque fois que je relance les applications (qjackctl,jackd, les threads jack-rack) les impulsions des 2 voies se désynchronisent (autrement dit le delai entre le flux du canal1 et 2 jusqu'à la sortie n'est pas fixe lorsqu'on relance les processus .
De même, si j'ajoute un plugin dans un des 2 threads jack-rack, il se peut que le délai du flux en question varie encore (délai augmenté).
Je suis donc devant un problème de latence que j'aimerai résoudre en appliquant tout les effets par une seule application, en appliquant les effets dans une seule fonction, et uniquement une fois tout les effets appliquer, effectuer une copie memoire vers les ports de sorties pour que les canaux soient tous synchronisés. J'ai déjà réussi a utiliser l'API jack, avec une appliation qui gère 8 canaux (je dois réaliser un 4voies stéréo) et implémenter des délais réglables sur chaque voie avec un buffer (circulaire ?) (un buffer de 20000 samples inialisé a 0 qui enregistre les samples du port in avec un index de (i+delay)%20000, et je renvoie les samples d'index i%tailledubuffer du buffer). Ainsi les samples qui rentrent et qui sont stockés a l'index n+delay sont lus avec "delay" samples de retard, et a chaque tour de buffer on revient au début.
Je n'ai cependant aucune idée pour implémenter les effets LADSPA ! Faut-il que je code mon propre "host" de plugin intégré a mon appli jack ? Comment faire ?
Le site de LADSPA donne des infos pour développer ces propres plugins, mais concernant le "hosting" de plugins, je n'ai trouvé aucune information (je ne sais pas du tout ou chercher).
3- Les filtres FIR ajoutent du délai inévitable au signal (phase linéaire mais group delay de (N-1)/2 taps, plus le filtre FIR est précis plus le retard est important). Enfin, je vois mal comment implémenter la convolution des samples avec les "blocs" de sample que jack envoie par période : sur le domaine temporel je ne vois pas comment faire, sur le domaine fréquentiel il faudrait idéalement que le filtre soit appliqué sur des parties de signal périodique (sinon obligé d'appliquer des fenêtres qui réduisent les infos, et plus les blocs de samples sont petits plus les pertes seraient importantes). Donc beaucoup de problèmes d'implémentation se posent pour moi, la solution serait peut-être un buffer circulaire de taille bcp plus grande, et scinder les parties du buffer en signaux périodiques (sample début ~= sample fin).
Comme le signal croise souvent 0, il est facile de "couper" le signal apériodique en petites parties "périodiques" pour appliquer le filtre sur le domaine fréquentiel et reconstituer le signal original ensuite.
Mon système ayant besoin d'avoir la latence la plus faible possible (j'utilise le système pour traiter le son qui sort d'une console donc le retard doit être non perceptible ;))
4- Je me suis alors penché vers les filtres IIR (avantage pour la coupure dans les basses fréquences mais plus de linéarité de phase .
Apparement les calculs sont bien inférieurs aux filtres FIR mais je ne comprend pas comment les "designer", "implémenter", je ne comprend pas non plus la notion de "poles" etc.
J'ai cependant trouvé un plugin (le plugin "lowpass_iir_1891.so") qui permet de choisir la fréquence de coupure et le nombre de stage pour régler l'ordre du filtre (plus l'ordre est élevée plus la phase est perturbée). Le code source n'est pas accessible, et je ne sais pas comment est appliquer le filtre pour contrôler que ces "séparations" par "blocs" ne perturbe pas l'application correcte du filtre.
Ce plugin serait parfait si j'arrivais a l'intégrer sur mon appli jack, d'ou une réponse a ma question 2 m'aiderait énormément !
J'ai aussi tenté d'utiliser ecarack pour charger les plugins sur ecasound, mais j'obtiens une erreur de fichier introuvable lorsque j'essaie de charger un .rack qui fonctionne sur jack-rack.... J'ai également tenté ingen (j'ai eu un pb de compilation donc j'ai supprimé un dossier des plugins lv2 et les liens de compilation, et après j'ai pu l'installer), mais celui-ci plante également et la doc est quasi-inexistante (peut-être a cause de la manip pour bypasser l'erreur de compilation ?)
Voilà si quelqu'un (Chritophe ? ) peut me fournir quelques aides sur ces concepts je serai ravi !
Je suis ici car j'utilise Jack pour effectuer du filtrage actif a partir de mon pc, et je manque cruellement d'informations quant à la synchronisation temporelle des flux audio de jack...
Je vais donc poser quelques questions primaires dont vous aurez, étant développeurs, certainement la réponse :
1- comment est déterminée la latence du serveur jack ? Je m'explique : jack a une latence fixe indiquée que Qjackctl qui est apparemment du nombres de frames / period * nombres de périodes/fréquence de sampling.
frames = samples
frames/period*period = buffer ?
Je ne comprend pas très bien comment est assuré cette latence. Je m'explique :
Si j'ai le schéma suivant dans les connections jack:
appli_1-out ==> appli_2-in
appli_2-out ==> system:output
Est-ce que le temps de latence est le temps de latence annoncé sur l'interface Qjackctl ou 2x le temps de latence ? (puisque le signal fais 2 fois le chemin avant de sortir par la carte son ?)
2- J'utilise les plugins LADSPA pour appliquer des filtres passe-bas/passe-haut sur plusieurs canaux de mon système. Ces plugins sont hostées par des threads jack-rack. J'ai des problèmes quant à la synchronisation des delais des canaux. Je m'explique encore, par exemple j'ai ceci :
canal 1 ==> jack-rack-lowpass ==> system:out1
canal 2 ==> jack-rack-highpass ==> system:out2
Dans le thread jack-rack-lowpass j'ai divers plugins : un filtre IIR lowpass, un simple_amplifier, et admettons plusieurs simples bandes paramétriques (nombre indéterminé).
Lorsque j'effectue des mesues de mon système, le délai en samples des réponses d'impulsions des 2 voies ne sont pas constants. Je suis donc obligé d'appliquer un delai sur 1 canal pour scinder les 2 impulsions, repérer leur décalage, et calculer le décalage réel sans le délai que j'ajoute. Ainsi, en supprimant le délai, j'ai normalement les 2 impulsions des voies "grave" et "aigu" qui se superposent en phase. Le problème est qu'a chaque fois que je relance les applications (qjackctl,jackd, les threads jack-rack) les impulsions des 2 voies se désynchronisent (autrement dit le delai entre le flux du canal1 et 2 jusqu'à la sortie n'est pas fixe lorsqu'on relance les processus .
De même, si j'ajoute un plugin dans un des 2 threads jack-rack, il se peut que le délai du flux en question varie encore (délai augmenté).
Je suis donc devant un problème de latence que j'aimerai résoudre en appliquant tout les effets par une seule application, en appliquant les effets dans une seule fonction, et uniquement une fois tout les effets appliquer, effectuer une copie memoire vers les ports de sorties pour que les canaux soient tous synchronisés. J'ai déjà réussi a utiliser l'API jack, avec une appliation qui gère 8 canaux (je dois réaliser un 4voies stéréo) et implémenter des délais réglables sur chaque voie avec un buffer (circulaire ?) (un buffer de 20000 samples inialisé a 0 qui enregistre les samples du port in avec un index de (i+delay)%20000, et je renvoie les samples d'index i%tailledubuffer du buffer). Ainsi les samples qui rentrent et qui sont stockés a l'index n+delay sont lus avec "delay" samples de retard, et a chaque tour de buffer on revient au début.
Je n'ai cependant aucune idée pour implémenter les effets LADSPA ! Faut-il que je code mon propre "host" de plugin intégré a mon appli jack ? Comment faire ?
Le site de LADSPA donne des infos pour développer ces propres plugins, mais concernant le "hosting" de plugins, je n'ai trouvé aucune information (je ne sais pas du tout ou chercher).
3- Les filtres FIR ajoutent du délai inévitable au signal (phase linéaire mais group delay de (N-1)/2 taps, plus le filtre FIR est précis plus le retard est important). Enfin, je vois mal comment implémenter la convolution des samples avec les "blocs" de sample que jack envoie par période : sur le domaine temporel je ne vois pas comment faire, sur le domaine fréquentiel il faudrait idéalement que le filtre soit appliqué sur des parties de signal périodique (sinon obligé d'appliquer des fenêtres qui réduisent les infos, et plus les blocs de samples sont petits plus les pertes seraient importantes). Donc beaucoup de problèmes d'implémentation se posent pour moi, la solution serait peut-être un buffer circulaire de taille bcp plus grande, et scinder les parties du buffer en signaux périodiques (sample début ~= sample fin).
Comme le signal croise souvent 0, il est facile de "couper" le signal apériodique en petites parties "périodiques" pour appliquer le filtre sur le domaine fréquentiel et reconstituer le signal original ensuite.
Mon système ayant besoin d'avoir la latence la plus faible possible (j'utilise le système pour traiter le son qui sort d'une console donc le retard doit être non perceptible ;))
4- Je me suis alors penché vers les filtres IIR (avantage pour la coupure dans les basses fréquences mais plus de linéarité de phase .
Apparement les calculs sont bien inférieurs aux filtres FIR mais je ne comprend pas comment les "designer", "implémenter", je ne comprend pas non plus la notion de "poles" etc.
J'ai cependant trouvé un plugin (le plugin "lowpass_iir_1891.so") qui permet de choisir la fréquence de coupure et le nombre de stage pour régler l'ordre du filtre (plus l'ordre est élevée plus la phase est perturbée). Le code source n'est pas accessible, et je ne sais pas comment est appliquer le filtre pour contrôler que ces "séparations" par "blocs" ne perturbe pas l'application correcte du filtre.
Ce plugin serait parfait si j'arrivais a l'intégrer sur mon appli jack, d'ou une réponse a ma question 2 m'aiderait énormément !
J'ai aussi tenté d'utiliser ecarack pour charger les plugins sur ecasound, mais j'obtiens une erreur de fichier introuvable lorsque j'essaie de charger un .rack qui fonctionne sur jack-rack.... J'ai également tenté ingen (j'ai eu un pb de compilation donc j'ai supprimé un dossier des plugins lv2 et les liens de compilation, et après j'ai pu l'installer), mais celui-ci plante également et la doc est quasi-inexistante (peut-être a cause de la manip pour bypasser l'erreur de compilation ?)
Voilà si quelqu'un (Chritophe ? ) peut me fournir quelques aides sur ces concepts je serai ravi !