< Back to IRCAM Forum

Aide avec les listes

Bonjour,

Je me permets de solliciter votre aide pour réaliser dans OM une fonction.

J’aimerais prendre une liste de liste, et agir sur ces listes en fonction des éléments qu’elles contiennent.

Par exemple, j’aimerais trier les listes dans l’ordre croissant de leur n-ième élément.
Et aussi, supprimer les listes qui ont leur n-ième élément égal.

J’ai commencé à explorer les fonctions, mais je suis tombé sur un os avec posn-order.

Sauf erreur de ma part, la fonction ne renvoie pas ce à quoi je m’attends, à savoir les positions des objets après les avoir triés. Est-ce un bug ou une mauvaise compréhension de son fonctionnement ?

Ci-dessous, le premier résultat dans le Listener est la sortie de posn-order, le second est la sortie de posn-match qui confirme malheureusement que les positions retournées par posn-order ne sont pas celles des éléments rangés dans leur ordre croissant.

Merci d’avance pour votre aide

Cyril

D’apres ce que vous voulez faire il faut proceder ainsi:
Screenshot_2024-06-08_19-57-22

le patch:
sort-rem.omp (2.4 KB)

Best
K

Bonsoir, merci pour votre réponse.

Pardonnez-moi je n’ai pas du être assez clair, c’est en fait sur les sublists que j’aimerais intervenir.

J’aimerais organiser certains éléments d’une liste, dont les éléments sont des sublists sous la forme de n-uplet (X1, X2,…, Xn), avec des tests sur les éléments X1,…,Xn des sublists.

Exemple de liste : ((6000 50) (6200 40) (6300 30))

Deux tests que j’aimerais effectuer dans un premier temps :

  1. éliminer de la liste les sublists qui ont le même Xi
  2. trier les sublists dans l’ordre de leur Xi croissant/décroissant

Concernant posn-order, fonctionne-t-il de votre côté ?

Bien à vous

Cyril

Sans souci,

Le patch:
sort-rem 2.omp (5.8 KB)

Best
K

PS: posn-order n’aime pas les duplicates justement.

A propos de posn-order:

le patch:
a_propos_posn-order.omp (7.2 KB)

Bien a vous
K

Bonjour,

Merci beaucoup pour votre réponse rapide !

Comment s’il vous plaît adapter ce patch pour appliquer plusieurs tests en même temps sur les différents Xi ?

Par exemple, le patch que vous m’avez fourni retire les sublists en testant l’égalité des X1, mais les Xi qui suivent devraient être également testés.

Par exemple, comment faire en sorte que la sublist retenue, après avoir éliminé ses doublons en testant X1, soit celle dont le X2 était maximal ?

Avec cet exemple : ((6000 50) (6800 70) (6300 30) (6400 50) (6000 10) (6100 4) (6400 5) (6000 6) (6800 7))

On n’aurait pas : ((6000 6) (6100 4) (6300 30) (6400 5) (6800 7))

Mais plutôt : ((6000 50) (6100 4) (6300 30) (6400 50) (6800 70))

Les nombres en gras étant les X2 max (pour un même X1) qui ont permis de choisir quelle sublist garder après élimination des doublons testés avec X1.

L’idéal serait d’avoir un patch général qui prendrait une liste de sublists (X1,…Xn) et qui prendrait de plus en entrée : les Xi que l’on veut tester (leur position dans la sublist), le test à appliquer dessus (eq, <,>…), et si l’on veut exclure ou garder les sublist qui vérifient tous les test en même temps.

Les test se faisant en cascade dans l’ordre des Xi donnés en entrée, cad que sont sélectionnées d’abord les sublist qui vérifient le test sur le premier Xi, puis parmi ces sublists retenus on effectue le deuxième test sur le deuxième Xi donné en entrée etc. (on pourrait choisir n’importe quel Xi à tester en premier, second… pas forcément X1, X2…).

Merci par avance !

Cyril

Le plus simple c’est de reccourrir au code lisp (toutefois il est possible aussi de le faire graphiquement):

D’abord creer une fonction qui “sort” la liste selons son CAR et mettre tous les seconds elements en CDR:

en utilisant une expression lisp.

Puis vient un omLOOP qui ne retient que l’element le plus grand du CDR:

Voila le dossier (a unzipper) et importer dans le Workspace:

parse_and_sort.zip (2.3 KB)

Bien a vous
K

Merci beaucoup, je vais étudier cela et je reviens ici si je ne parviens pas à le faire fonctionner.

Au passage, j’aimerais retirer les accords d’une liste lmidic. Pourquoi ci-dessous ma fonction lambda ‘doesn’t match’ ?

Bien à vous

Cyril

Reponse:

Patch:
listfilter.omp (6.4 KB)

Best
K
PS: SVP si possible envoyer le patch. Cela m’evitera de retaper les donnees.

Merci cela fonctionne bien. Je comprends mieux en effet. J’ai cru à tort qu’avec une list of lists, le test pouvait s’appliquer récursivement sur les sublist.

De manière générale avec OM, plutôt que d’agir sur une liste, comment agir sur des vecteurs ?
Par exemple, chaque accord d’un chord-seq est un vecteur dont les coordonnées sont mdic, onset, dur, vel etc. Si je veux supprimer un accord, j’aimerais supprimer toutes les coordonnées du vecteur.

Il existe des fonctions qui permettent de travailler sur des matrices ?

Bien à vous

Cyril

Cher Cyril.

Par vecteurs j;imagine que vous faites allusion a la structure de donnee Python. En effet, dans Lisp il exitse les Array (matrices) mais leurs manipulation est un peu complique.

Par contre pour votre probleme que vous sous-entender on peut proceder d’une maniere simple et elegante a savoir proceder par objets. Common Lisp (CLOS) et un des premiers Langage oriente objet, (mais la encore je ne suis pas specialiste en histoire des langages informatiques).

Si il est question de “manipuler” des objets internes par exemple au chord-seq c’est assez directe. La question est “qu’est-ce que vous voulez faire?” a savoir pouvez vous me donner un exemple (+ ou - detaille) de votre idee de proceder. Comme cela je pourrais vous fournie des exemples pratiques sans passer a construire des matrices a partir d’objets deja hierarchises.

amitites
K

Bonjour,

Non je ne fais pas référence à Python, ni à aucun langage informatique car je n’en maitrise aucun, mais simplement au concept mathématique. J’appelle ‘vecteur’ une note dans un chord-seq car c’est un objet qui comporte plusieurs variables, que je peux appeler ‘coordonnée’ (midic, onset, dur, vel etc.).

Le problème est lorsque l’on manipule l’une de ces coordonnées en sortie d’un chord-seq, par exemple la liste des midic, on n’intervient pas en même temps sur les autres coordonnées associées. Si je supprime une note dans lmidic, les autres variables associées (onset, dur etc.) ne sont pas supprimées.

Dans un cas simple, par exemple, la gamme de Do à 60 à la noire dans un chord-seq A, si je veux supprimer la 5te puis afficher la nouvelle gamme dans un chord-seq B, je dois prendre chaque liste lmidic, lonset etc. et supprimer le 4ème élément de chacune d’elle, puis enfin rentrer les nouvelles listes dans les slot correspondants du chord-seq B. C’est la façon simple en manipulant les indices, mais cela suppose de les connaître.

Mais je me demandais s’il n’était pas possible de manipuler plus globalement ces vecteurs, qui sont les évènements sonores d’un chord-seq, en manipulant les tableaux qui les représente : chaque colonne sont les coordonnées (note, dur, vel etc.) et chaque ligne un vecteur (numéro de la ligne = indice dans toutes les listes).

Je vais donc regarder de plus près les array dans Om, mais en somme ce que j’aimerais faire c’est appliquer toute sorte de fonctions test (tri, suppression…) sur les coordonnées des vecteur (note, dur, vel…) d’un chord-seq A, et rentrer les vecteurs résultants dans un chord-seq B.

Un premier écueil rencontré est que parfois, dans lmidic, un vecteur comporte plusieurs notes pour un même onset. Il sera préférable d’avoir deux notes ‘individualisées’ : (6000) (6200) plutôt que (6000 6200), mais avec le même onset, afin de garantir la même longueur pour toutes les listes des coordonnées de vecteur : lmidic, lonset etc.

Bien à vous

Cyril

Je peux résumer la structure de comment j’aimerais utiliser les matrices ainsi :

vecteur = colonne = événement sonore dans un chord-seq

exemple avec 7 évènements sonores

matrice résultante du chord-seq :

lmidic : (6000 6000 6200 6100 5800 6900 6200)
lonset : (0 100 200 300 400 500 600)
ldur : (7500 6500 5500 4500 3500 2500 1500)
lvel : (50 40 45 20 79 82 38)

Exemples de fonctions à appliquer sur la matrice :
- retirer les colonnes dont la valeur de vel est <50
- ranger les colonnes par ordre croissant des midic
- supprimer les colonnes ayant le même midic ET garder celle avec le vel maximal.

Rentrer la nouvelle matrice dans un chord-seq pour afficher les nouveaux événements sonores.

Cher Cyril,

Pas la peine de s’embeter avec les arrays. C’est plus simple ainsi:
Exemple ou on retire la quinte:

Le patch:
exemple-1.omp (11.0 KB)

Pour votre exemple ci-dessus, est-il possible de m’envoyer le patch?

K

Super, en effet cela fonctionne bien comme ça.

Si je veux maintenant appliquer des fonctions de filtrage des chords avec des test sur leurs différents paramètres (midic, onset, dur, vel…), comment pourrais-je intercaler ces fonctions entre les deux chord-seq ? Si je rajoute des entrées à mapcar, je peux créer une liste de type ( (midic) onset (dur) (vel)). C’est sur les éléments de cette liste que j’aimerais appliquer des fonctions de filtrage.

Dans le patch joint j’ai repris l’exemple et ajouté un commentaire avec des exemples de fonctions de filtrage et j’ai chargé le chord-seq pour en avoir un plus complexe.

Si vous pouviez me donner la structure générale pour appliquer une fonction de filtrage sur n’importe quel élément de la liste en sortie de mapcar !

Bien à vous

Cyril

exemple-1.omp (23.2 KB)

Procedons deja par un truc simple (votre premier exemple):

Patch:
exemple-2.omp (40.6 KB)

Ici on applique

  • un filtrage des valuer de velocitee < 50
  • un sort des midics.

Seulement voila, c’est bien le probleme ici, les CHORDS sont tous a une note.
Dans le patch que vous avez envoyer. il y a aussi des CHORDS avec plusierus notes, ce qui implique soit:
a- de faire une recursivite (un peu complique pour le moment,
b- soit de transforme tous les chords a n notes > 1 en plusieurs chords avec meme onset.

Cela fera u exemple a venir.

Amitites
K

Bonsoir,

J’ai bricolé un bout de patch (avec les fonctions que j’ai découvert jusqu’alors) qui transforme les chords à 2 notes en 2 chords de 1 note, et qui duplique le onset correspondant.

Je ne sais pas comment faire pour retourner à partir d’une liste les positions des éléments qui vérifient un test (en l’occurence ici pour lmidic, les éléments dont la longueur est supérieure à 1).

Cela permettrait de le généraliser pour tous les chords de plusieurs notes.

exemple-1 3.omp (13.6 KB)

Bien à vous,

Cyril

Bonsoir,

De mon cote:

get-chord-onset et une solution pour avoir le onset d’un CHORD appartenant a un CHORD-SEQ. NOTE: ne marche pas pour un CHORD isole (c-a-d n’appartenant pas a un CHORD-SEQ).

unalign-chords est ma solution pour “spliter” les CHORDS a plusieurs notes.
align-chord est une fonction interne OM qui rassemble les notes dans un delta pour les concatener en un accord. (ici on utilise zero).

le patch:

utilities.omp (28.6 KB)

Bonsoir

K

Merci beaucoup ! Je vais explorer tout ça.

Je vois beaucoup de fonctions lisp que l’on ne retrouve pas sur cette page : file:///Applications/OM%207.4.app/Contents/Resources/reference/index.html

Comme inside, parent, position…

Ce sont des fonctions de base en lisp si j’ai bien compris, mais quelle est svp la liste exhaustive de celles que l’on peut utiliser graphiquement dans OM ?

Bien à vous

Cyril

J’ai pu réaliser le patch désiré grâce à votre aide, je vous en remercie grandement !

Finalement la fonction pour détruire les chords m’a permis de manipuler des matrices, et grâce à la fonction omloop je n’ai qu’à choisir l’indice pour décider sur quelle composante (midic, onset…) je veux appliquer le filtre.

Enfin si je veux appliquer deux filtres en même temps je peux utiliser l’intersection des deux matrices.

Je n’ai pas compris ce qu’apportait la fonction lisp ‘lvel’, ni l’intérêt du clone et slots, si vous pouvez me l’expliquer, j’en apprendrais davantage !

Bien à vous

Cyril