< Back to IRCAM Forum

Function for calculating a Table of Frequencies and Ratios?

Hi Karim,
I want to create a function with “defmethod” and “defun” to create a table with the joint display of indices / ratios and Hz frequencies. The idea is to calculate the progress tables established by Augusto Novarro and published in part by Jean-Etienne Marie in his book “L’Homme Musical”. With a patch, I can do it (screenshot).

CalcHZ24Patch

On the other hand, with a “defun” or “defmethod!” I manage to calculate separately a single index / ratio or a single frequency but I cannot integrate the iterative calculation to create a table jointly displaying the indices / progress ratios and the Hz frequencies as with the patch (copy of screen).
Hence my question, how to insert in functions created with defun and defmethod! the iterative calculation of progressions according to the temperament chosen and obtained in the patch with “om ^” and “arithm-ser”? I tried with the “loop” function but I could not link it with the second “om ^” to simulate “om ^ <- arithm-ser” * 261.63 " as in the patch.
The code with “defun”:
(in-package :om)
(defun defunHzval_dd (x y z f)
(values (* (om^ x (/ y z)) f)))
The code with defmethod! :
(in-package :om)
(defmethod! defcalcHzfloat_dd ((x integer) (y integer) (z integer) (f float))
:numouts 1
(values (* (om^ x (/ y z)) f)))
Merci d’avance.
Amitiés. Didier

Je joins le texte en français :
Je souhaite créer une fonction avec “defmethod” et “defun” pour créer une table avec l’affichage conjoint des indices/ratios et des fréquences Hz. L’idée c’est de calculer les tables de progressions établies par Augusto Novarro () et publiées en partie par Jean-Etienne Marie dans son livre “l’Homme Musica"l. Avec un patch, je sais le faire (copie d’écran). En revanche, avec une fonction “defun” ou “defmethod!” j’arrive à calculer séparément un seul indice/ratio ou une seule fréquence mais je n’arrive pas à intégrer le calcul itératif pour créer une table affichant conjointement les indices/ratios de progression et les fréquences Hz comme avec le patch (copie d’écran).
D’où ma question, comment insérer dans les fonctions créées avec “defun” et “defmethod!” le calcul itératif des progressions selon le tempérament choisi et obtenu dans le patch avec “om^” et “arithm-ser” ? J’ai essayé avec la fonction “loop” mais je ne suis pas arrivé à la lier avec le deuxième “om^” pour simuler “om^<-arithm-ser” * 261.63” comme dans le patch.

1 Like

hum, do you mean iterative or recursive ?

Hi Didier,

Something like that ?

Maybe you need to tweak something here…
funct_didier.lisp (322 Bytes)

Best
K

Karim, Un très grand merci pour cette fonction. Je vais la décortiquer pour bien assimiler la syntaxe car ça me donne vraiment envie d’approfondir. Je savais qu’il fallait inclure notamment la fonction “let” combiné à un “loop” mais jamais je n’aurais pensé à l’insérer ainsi : “(all (loop for i from 0 to (denominator rat)”, en faisant appel au dénominateur du ratio. Pour la suite, les autres variables, même remarque avec les calculs “((div (expt num rat))”, “collect (expt div i)))”, “(mult (om* all freq)))” mais à bien regarder c’est logique. J’ai remplacé pour voir “expt” par “om^” et ça fonctionne aussi.
Sinon, je suppose que pour "let*, le “*” permet de déclarer plusieurs variables et de fait plusieurs opérations ?
Amitiés.
Didier

plus precisemment le let* permet non seulement de declarer plusieurs variables (ce que fait aussi let sans asterix) mais que certaines des variables ainsi declarees dependent de celles declarees precedemment dans la meme declaration (ce que ne fait pas let sans aterix).

Ainsi par exemple il peut etre plus simple d’ecrire:
(let* ((a 0) (b (+ a 1)))
(print b))

plutot que:
(let ((a 0) (b nil))
(setf b (+ a 1)))
(print b))

mais ce n’est pas toujours possible et parfois la deuxieme forme s’impose pour diverses raisons.

Bienvenue dans ce langage magnifique tant pour sa simplicite que pour la liberte qu’il offre !
S’il existait des processeurs natifs en lisp (il y en a eu) ce langage ne serait pas plus lent que le C !

Fred Voisin : hum, do you mean iterative or recursive ?
Fred, il me semblait que c’était un calcul itératif avec une incrémentation avec un pas défini mais du coup je doute car je vois qu’il y a des fonctions récursives avec incrémentation…

Fred Voisin : “plus precisemment le let* permet non seulement de declarer plusieurs variables (ce que fait aussi let sans asterix) mais que certaines des variables ainsi declarees dependent de celles declarees precedemment dans la meme declaration (ce que ne fait pas let sans aterix).”

Merci pour la précision sur le “let*” et les deux exemples… Si tu as des liens avec une bonne documentation, je suis preneur. Là, je sèche sur un truc tout bête que je fais sans problème avec OM dans un patch, à partir d’une liste en midicents (MC), la diviser par 100 puis la diviser avec une division euclidienne avec le diviseur en modulo 12 et en ne conservant que le reste, ce qui permet de convertir successivement les notes MC (6700 7200 7800) en note midi (67 72 78) => (7 0 6)…

Cher Didier,

Est-ce bien cela: ?

Screenshot_2020-10-17_18-50-30

1 Like

…and here the lisp equivalent:

The code:
funct_didier1.lisp (209 Bytes)

Cher Karim, encore un grand merci, c’est exactement ça. Hier soir et ce matin, j’essayais de trouver comment afficher le “reste” de la division euclidienne, mais le résultat était une suite d’erreurs. Et là, je découvre la solution. Donc, OK pour la division par 100 pour obtenir les notes midi, ça correspond à ce que je fais avec un patch/abstraction, mais encore une fois, je n’aurais pas trouvé cette macro “loop for i in midi” - c’est bien une macro ? - mais après une recherche je constate qu’elle est bien documentée tout comme la conversion modulo 12 avec “mod i 12”. Comme pour l’autre fonction, je vais étudier cette syntaxe.
Amitiés.
Didier

Cher Didier,

Le loop c’est bien une macro assez developpee qui convient a bien de choses. C’est un peu comme un couteau suisse reunissant mapcar, reduce, et bien d’autres choses imaginables. cf. : http://cl-cookbook.sourceforge.net/loop.html . omloop est la version “graphique” implementee dans OM. C’est bien utile…

Amities
K

Cher Karim,
Merci pour le lien. Il va compléter celui que j’ai trouvé : https://lispcookbook.github.io/cl-cookbook/iteration.html
Amitiés.
Didier