Audacity et Nyquist

Forum Audacity
Forum
jzu
  • jzu
  • Custom Méga utilisateur
  • MP
  • #1
  • Publié par
    jzu
    le 03 Feb 08, 17:53
Avertissement : geek-friendly topic !

J'utilise pas mal Audacity, surtout pour faire du montage-découpage, et je voudrais m'en servir pour créer des effets. En ce moment, j'étudie la composition harmonique des distorsions. Jusqu'à présent, je téléchargeais les sources et je créais un effet en C++ (en fait, la syntaxe du C suffit) en appliquant une fonction sur les éléments du tableau appelé *buffer qui contient la sélection en cours. Exemple simple extrait d'un fichier Disto.cpp que j'ai créé :

Citation:

bool EffectDisto:: ProcessSimpleMono(float *buffer, sampleCount len)
{
sampleCount i;
for (i = 0; i < len; i++)
buffer[i] = sin(buffer[i]*3.14592/2);
return true;
}


(zut, il n'y a plus la balise [code]...)

Et puis j'ai découvert un langage intégré dans Audacity qui s'appelle Nyquist, permettant de scripter des plug-ins qu'on met simplement dans un répertoire standard et hop, l'effet est là. On peut aussi ouvrir la « Console Nyquist » dans le menu Effets pour tester un algo.

Citation:

(cue (mult s 2))



cue semble renvoyer le résultat là où il faut (dans la sélection), mult est une fonction de multiplication adaptée aux samples et s contient la sélection en cours. Ici, j'ai multiplié chaque sample par 2, c'est à dire que j'ai augmenté le niveau de 3 dB. Il y a des tas de primitives d'assez haut niveau pour jouer sur la fréquence du son, son enveloppe, pour moduler en anneau, pour mettre du delai, j'en passe et des meilleures.

Le langage est un dialecte de Lisp, donc un langage fonctionnel plein de S-expressions et de lambda-calcul. Rien à voir avec un langage impératif comme le C mais on s'en tire dès qu'on a compris 2 ou 3 notions. Seulement voilà, je n'arrive pas à appliquer une fonction sinus (ou un polynôme) aux samples pour générer des harmoniques, elle prend un argument et basta. Alors, comment faire ? Est-ce que quelqu'un s'est déjà coltiné toute la doc et les exemples (en cours pour ma part), et a réussi quelque chose dans cet esprit ?
Invité
Lisp, Lisp... Ca serait pas un genre de langage méga-abstrait sans le moindre intérêt pratique, ça ?? Ou je confond ?
EDIT : Oh putain, si, je vois, c'est le langage cauchemar avec les parenthèses de partout !!! Une vraie horreur syntaxique...

Moi je te suggère de rester en C. C'est pragmatique, c'est simple, c'est efficace, c'est universel. Et comme c'est bas niveau, ca te forme normalement un peu pus que de coller des boites ensembles, niveau traitement du signal.

Et puis un langage qui s'appelle Nyquist... Pourquoi pas Pythagore ou Einstein, tant qu'on y est ??

"Moi je code en Einstein, et toi ?"
jzu
  • jzu
  • Custom Méga utilisateur
  • MP
  • #3
  • Publié par
    jzu
    le 03 Feb 08, 23:46
Lisp : Lots of Irritating Superfluous Parentheses, on est bien d'accord. Mais ce n'est pas sans intérêt pratique puisque c'est comme ça qu'on écrit des macros en Emacs et que je configure mon window manager, Sawfish. C'est bon ? Je t'ai convaincu ? :mdr:

Le problème du C, c'est qu'il faut le compiler pour que ça marche et ensuite le bouzin est intégré en dur dans l'appli. Si je veux passer un effet à quelqu'un, je fais comment ? Je m'en suis tiré sur ma Debian à grand coups de apt-get install wxmachinchose-dev (2.6, important, parce que ça ne marche pas avec le 2.4, ce genre de joyeuseté), rien que pour pouvoir faire ./configure et make, mais je n'ose pas imaginer l'horreur pour une personne, euh, normale, qui veut juste utiliser le truc. Et s'il faut le faire sous Windows, je ne connais pas le début du commencement de la procédure de compilation.

Alors que les plug-ins d'Audacity sont des fichiers texte qui sont prêts à être utilisés dès qu'on les dépose dans un répertoire précis (/usr/share/audacity/plug-ins/ chez moi). Si je veux en passer un que je trouve réussi à un copain, je le lui envoie et il peut tourner sous Windows ou sous MacOS X, ça n'a aucune importance.

Il reste juste un léger détail à régler : comment ça marche ? C'est d'autant moins gagné que la version intégrée à Audacity est un sous-ensemble du langage et que donc les exemples mettant en jeu des fonctions de transfert plantent lamentablement. Il faut installer le package nyquist lui-même, qui a un shell en ligne de commande, pour les faire tourner. Mébon, il n'est pas nécessaire d'espérer pour entreprendre ni de réussir pour persévérer. Je sens que je vais persévérer longtemps.
jzu
  • jzu
  • Custom Méga utilisateur
  • MP
  • #4
  • Publié par
    jzu
    le 13 Feb 08, 12:17
J'ai correspondu sur la liste Audacity-Nyquist pour avoir des infos et le mainteneur, Edgar, est très actif : il m'a fourni tous les éléments pour faire le plugin que je désirais. En l'occurrence, il s'agissait d'expérimenter un compresseur statique comme une distortion ou un étage d'ampli à lampes.

:

;nyquist plug-in
;version 3
;type process
;name "Shape..."
;action "Performing Shape Effect..."
;control what "Choose:" choice "Apply effect,Show function,Show variables" 0 

(setf *gc-flag* nil)  ; no garbage collector messages please

;; *sound-srate*  is the sample frequency of the Audacity track
;; array-size     is the number of all steps from -1.0 to +1.0
;; step-size      is the size of a single step

;; Because 0 [zero] in physics is NOT a positive number like wrongly
;; handled in most computer programming languages we need a sound of
;; two seconds length PLUS one sample

;; because *sound-srate* is a float but arrays cannot be initialized
;; by using floats we must use the truncate function to make array-size
;; become an integer

(setf array-size (+ (* (truncate *sound-srate*) 2) 1))
(setf step-size (/ 1.0 *sound-srate*))

;; make shape-array a local variable so the memory can be freed
;; if neccessary during the shape transformation process
;;
(when (< what 2)
  (let ((shape-array (make-array array-size)))
    ;; fill the array with the transformation data
    (dotimes (i array-size)
      (setf (aref shape-array i)
        ;;
        ;; replace the following line with your own function[s]
        ;;
        (- 1.0 (* step-size i))
      ))
    ;; turn the filled array into a sound
    (setf *shape* (snd-from-array 0.0 *sound-srate* shape-array))))

(defun shape-transform (snd)
  (shape snd *shape* 1.0))

(cond ((= what 0) (shape-transform s))
      ((= what 1) *shape*)
      ((= what 2) (format nil "Array size: ~a~%Step size: ~a~%"
                              array-size step-size)))



Ça a l'air compliqué, surtout en perdant l'indentation (Edit : yeah ! en fait ça marche !), mais en fait... ça l'est. C'est la mauvaise nouvelle.

La bonne nouvelle est qu'on a ici un framework où il suffit de remplacer une ligne, le simple inverseur

:
(- 1.0 (* step-size i))

pour y mettre la fonction qu'on veut, comme par exemple

:
(cos (* 1.573 (* step-size i)))

et hop, on aplatit doucement l'onde comme sur une disto au germanium. On peut aussi employer des log (donne un son plus propre) et des racines carrées pour y arriver mais on dirait qu'il y a un petit problème d'implémentation, en cours de résolution.

C'est facile à tester, il suffit de copier/coller le source dans la Console Nyquist d'Audacity et de lancer plusieurs fois pour obtenir une onde de plus en plus compressée et un son de plus en plus distordu. On peut aussi créer un fichier shape.ny dans le répertoire des autres plugins et il sera accessible au prochain lancement d'Audacity.

On obtient donc des harmoniques tierces. Un ampli à lampes génère en plus des harmoniques secondes et j'ai l'impression qu'il faut désymétriser l'onde pour y arriver. Ça ne va pas être de la tarte mais j'ai des idées pour faire ça à peu près proprement ; de plus, le nommé Edgar fabrique ses propres fuzz et amplis depuis 20 ans et a l'air motivé. Il va créer une page de recettes de cuisines (encore vide, voir l'url ci dessous) pour créer facilement des plugins de toutes sortes. Nyquist est un langage incroyablement riche et n'a pas volé son nom, gonflé mais justifié.

http://audacityteam.org/wiki/i(...)mming

En ce moment sur effet guitare et Audacity...