linuxmao-org / Frontieres

An Interactive Granular Sampler (unofficial fork)
GNU General Public License v3.0
26 stars 2 forks source link

Pilotage MIDI #5

Closed jpcima closed 4 years ago

jpcima commented 6 years ago

@trebmuh À détailler.

développer une entrée MIDI et une contrôlabilité MIDI pour pouvoir automatiser tout ça, voire jouer avec les potards d'une BCF 2000 ce qui améliorerait probablement l'ergonomie du logiciel. Ne pas oublier d'y adjoindre une fonctionnalité de MIDI-learn.

trebmuh commented 6 years ago

L'idée ici est de pouvoir assigner les contrôles du logiciel à des potentiomètres et des chariots sur des surfaces de contrôle MIDI, histoire de faciliter son utilisation car il est plus facile/marrant de tourner un potard que d'appuyer sur les touches du clavier alpha-numérique.

jpcima commented 6 years ago

Ici je pense que l'apprentissage MIDI sera important, puisque selon moi il va falloir être en mesure de pouvoir créer une association entre un contrôle MIDI avec un nuage particulier.

Les associations doivent pouvoir être exprimées en Control-Change, voire en NRPN. Quant aux notes et aux pitchbend je ne sais pas si on peut en faire quelque chose, alors si vous avez des idées..

trebmuh commented 6 years ago

il va falloir être en mesure de pouvoir créer une association entre un contrôle MIDI avec un nuage particulier.

"un nuage particulier" et/ou un "un échantillon" (un rectangle)

olof29 commented 6 years ago

si on veut associer un controleur midi à chaque grain, on va tres vite saturer en terme de possibilités. ce serait deja un bon debut de pouvoir piloter les parametres des clouds en midi. j'ai vérifié, la fonction midi présente dans Frontieres.cpp fonctionne. il est donc possible d'implementer des actions dedans. il nous faudrait definir exactement ce qu'on veut faire : on a acces à des messages note-on et note-off, avec en prime bien sur le numero de note et le numero de canal, mais aussi à des control change avec numero de controle, numero de canal, et valeur. on peut donc facilement dupliquer le code qui est appelé à l'appui d'une touche clavier, ou mieux, creer une methode appelée dans les deux cas, ce qui permetytrait aussi de les appeler depuis une fenetre graphique de Qt, par exemple, affichable pour le cloud selectionné

trebmuh commented 6 years ago

si on veut associer un controleur midi à chaque grain, on va tres vite saturer en terme de possibilités. ce serait deja un bon debut de pouvoir piloter les parametres des clouds en midi.

Je ne crois pas, ça dépend de l'utilisation d'un utilisateur. J'imagine qu'il suffirait probablement d'implémenter l'apprentissage MIDI et de ne pas coder en dur "qui fait quoi" dans le logiciel pour laisser chaque utilisateur définir ce qu'il veut contrôler et avec quel contrôle.

Si toi tu as envie de bosser sur un sujet qui t'intéresse particulièrement comme de contrôler les nuages en MIDI, vasy, c'est super. Mon conseil est d'essayer pour toi de penser à coder en pensant un peu plus loin (comme ce que j'ai abordé dans les messages précédents).

olof29 commented 6 years ago

du coup ça demanderait de gerer un parametrage des affectations des signaux midi, qui serait peut etre à integrer dans un fichier, peut etre un fichier de sauvegarde d'un projet (voir l'issue au sujet de la sauvegarde des projets). je vais garder ça à l'esprit dans mes essais. ça ressemble assez à une base de donnees, ça, non ?

olof29 commented 6 years ago

bon, il s'agit ici de bien définir toutes les idées qui nous viennent à l'esprit de type de pilotages midi pour voir si la maniere dont on developpera celui ci permettra de repondre à toutes ces envies. je vais donc enumerer celles qui me sont dejà venues à l'esprit.

bon, dejà avec ça y'a de quoi se prendre pas mal la tete. n'hesitez pas à enumerer vos envies possibles aussi. quoiqu'il en soit, se dessine deja une reflexion à avoir sur la façon dont on peut traduire une valeur envoyée par un element midi quelqu'il soit (souvent entre 0 et 127) et la valeur d'un parametre de cloud ou d'echantillon, qui elle peut avoir des façons de varier totalement differentes selon le parametre

jpcima commented 6 years ago

quoiqu'il en soit, se dessine deja une reflexion à avoir sur la façon dont on peut traduire une valeur envoyée par un element midi quelqu'il soit (souvent entre 0 et 127) et la valeur d'un parametre de cloud ou d'echantillon, qui elle peut avoir des façons de varier totalement differentes selon le parametre

A mon avis le plus simple est de normaliser toute valeur en domaine 0-1 et appliquer une courbe de contrôle. La courbe se définit en points de contrôle (x,y) et pour le besoin de la synthèse on conserve dans un tableau la version interpolée.

olof29 commented 6 years ago

ravi de voir ma suggestion comprise, mais malheureusement, moi je ne comprends pas la solution :)

olof29 commented 6 years ago

dans l'optique d'un expandeur midi, une autre fonctionnalité me plairait enormement.

olof29 commented 5 years ago

pour pouvoir faire de Frontieres un expandeur midi, il serait simple de rajouter 2 parametres aux clouds :

ainsi, on peut tres simplement :

olof29 commented 5 years ago

fonction de base midi proposée avec note on, note off, qui activent / desactivent des clouds. cela est un progres, mais me semble insuffisant :

olof29 commented 5 years ago

dans l'optique de la creation de cette nouvelle classe, voici verbalisées quelques idées à son propos :

olof29 commented 5 years ago

voici donc ce que pourrait etre cette classe :

combinaison :

instrument :

tout cela fait partie d'une scene, et peut etre mémorisé avec elle.

il faudrait peut etre aussi creer un parametre de verrouillage d'un cloud, afin que l'utilisateur puisse décider de ne pas permettre de le modifier par inadvertance lorsqu'il est utilisé dans des combinaisons (idem pour la position et la forme des samples)

olof29 commented 5 years ago

il y a des bugs dans l'implementation midi qui etait fournie à la base dans borderlands :

olof29 commented 5 years ago

bon, le canal midi n'est pas à 0 en fait, il est au numero de canal -1, et comme j'emettais sur le canal 1, il mettait 0, il me faut donc ajouter 1 au numero de canal reçu

jpcima commented 5 years ago

j'ai du echanger les code de note on et note off qui etaient inversés

Oui je confirme que les indications en commentaire sont erronnées.

bon, le canal midi n'est pas à 0 en fait, il est au numero de canal -1, et comme j'emettais sur le canal 1, il mettait 0, il me faut donc ajouter 1 au numero de canal reçu

Dans les messages midi, le canal est une valeur sur 4 bits, soit valuée de 0 à 15. Les interfaces graphiques, les documentations adressées aux utilisateurs, etc. désignent ces mêmes canaux dans le domaine 1-16.

Cela explique le décalage de 1, mais le calcul est juste. En programmation il est sage de conserver l'indiçage à 0, ce qui évite des erreurs de code un peu bêtes. (dès qu'il est question d'indicer un tableau, notamment)

olof29 commented 5 years ago

oui, c'est ce que j'ai fait pour cette meme raison.

maintenant , je me penche sur la question des combinaisons. pour cela, je patauge un petit peu :

jpcima commented 5 years ago

J'ai pas du tout réfléchi à la question pour l'instant, mais je me suis noté de faire ça un peu plus tard. N'est-ce pas possible de faire ça sans dupliquer les nuages ? Ne peut-on pas avoir des grains accordés sur différent tons ?

jpcima commented 5 years ago

constructeur de copie

Ce serait une éventualité, mais sous contrainte de temps réel cela rajoute de la complication, car on n'a pas le droits aux malloc/new, toute mémoire se réserve à l'avance. C'est pas impossible mais on peut accepter une version provisoire qui fait les allocs mémoire, on verrait ensuite.

olof29 commented 5 years ago

J'ai pas du tout réfléchi à la question pour l'instant, mais je me suis noté de faire ça un peu plus tard.

j'ai noté la strucutre que je pense utiliser quelques messages au dessus

N'est-ce pas possible de faire ça sans dupliquer les nuages ?

difficilement, à mon avis, si on veut un synthetiseur reellement polyphonique sur chaque cloud : il faut pouvoir simultanement jouer le meme cloud à des pitchs différents

Ne peut-on pas avoir des grains accordés sur différent tons ?

les grains ne sont à mon avis que des constituantes du son qu'on peut comparer à des harmoniques de celui ci, ils peuvent donc tout à fait etre accordés différemment de l'accord principal du cloud. selon moi, c'est à l'utilisateur de dire quelle est la note principale, quiite à ce que plus tard on lui fournisse des outils de détection de celle ci, mais en tout etat de cause, en raccordant la sortie à un simple accordeur, il devrait pouvoir le savoir. ensuite, selon la note midi voulue, le cloud copié sera repitché en comparaison avec la note principale

tout ça, je sais faire. seule la question de faire une copie sans creer une latence m'inquiète, mais sinon, je ne vois pas du tout comment rendre un cloud polyphonique avec différents pitchs.

jpcima commented 5 years ago

Ok j'aime bien l'idée. Tout de même, je pense qu'il serait bien que Cloud reste ce qu'il est.

Je verrais éventuellement un fractionnement de l'entité nuage, avec une relation 1→N avec une multitude de "variantes tonales de nuage". Le N peut être borné par un maximum tel que 32, comme une polyphonie de synthétiseur.

Je pense que l'interface graphique doit continuer à manipuler des instances de Nuage, en ajout/suppression, ce qui occupe le verrou de scène et donc constitue une opération pouvant occasionner une période d'arrêt.

Au contraire, les N "voix" (si on peut maintenant se permettre de réutiliser ce terme) pourraient être réservées en mémoire à l'avance, et seul le fil audio se permettrait de les manipuler. Cette opération serait compatible avec le temps réel.


J'en profite pour glisser un lien vers une structure de donnée que j'ai réalisée très récemment pour un synthé TR : https://github.com/jpcima/libADLMIDI/tree/std-structures/src/structures Il s'agit d'une liste chaînée qui réserve un espace borné réutilisable de N cellules, utile en ce genre de situation.

olof29 commented 5 years ago

Ok j'aime bien l'idée. Tout de même, je pense qu'il serait bien que Cloud reste ce qu'il est.

ça, dans mon idée, c'est le cas, et on peut tres bien melanger les deux façons de faire du son en continuant à travailler en temps réel sur les clouds, même si un musicien autre est en train de jouer en pilotage midi.

Je verrais éventuellement un fractionnement de l'entité nuage, avec une relation 1→N avec une multitude de "variantes tonales de nuage". Le N peut être borné par un maximum tel que 32, comme une polyphonie de synthétiseur.

c'est ce que je ne vois comment realiser, c'est pour ça que je me suis tourné vers la logique de copie temporaire du cloud.

Je pense que l'interface graphique doit continuer à manipuler des instances de Nuage, en ajout/suppression, ce qui occupe le verrou de scène et donc constitue une opération pouvant occasionner une période d'arrêt.

c'est quoi, ce verrou de scene dont tu parles ?

Au contraire, les N "voix" (si on peut maintenant se permettre de réutiliser ce terme) pourraient être réservées en mémoire à l'avance, et seul le fil audio se permettrait de les manipuler. Cette opération serait compatible avec le temps réel.

meme commentaire que ci dessus, ça je ne sais pas comment le gerer

J'en profite pour glisser un lien vers une structure de donnée que j'ai réalisée très récemment pour un synthé TR : https://github.com/jpcima/libADLMIDI/tree/std-structures/src/structures Il s'agit d'une liste chaînée qui réserve un espace borné réutilisable de N cellules, utile en ce genre de situation.

je vais jeter un oeil voir si j'y comprends quelque chose.

jpcima commented 5 years ago

C'est pas évident et ça demande de s'y pencher plus en détail, raison pour laquelle je ne sais trop te donner une réponse précise pour le moment.

C'est ça le verrou de scène: extern std::mutex currentSceneMutex; L'interface graphique occupe ce verrou durant l'ajout/suppression sur l'ensemble de nuages, et pendant ce court moment, c'est un signal à zéro qui sera produit sur la sortie sonore.

olof29 commented 5 years ago

pourtant, la suppression d'un cloud ne me semble pas creer d'interruption du rendu sonore des autres clouds actifs. ou c'est si court que je ne le décele pas, et s'il y a trop de destructions dues à une polyphonie comme je la pense, ça pourrait devenir audible ?

jpcima commented 5 years ago

J'ai fait que la prise du verrou soit réalisée sur la période la plus courte possible, donc il se peut que la discontinuité ne se produise que très rarement. Il n'empêche qu'elle est possible.

olof29 commented 5 years ago

bon, si je résume :

donc, je pense que, vu que mes capacités sont loin d'atteindre les tiennes, je peux me pencher sur la partie structure de cominaisons, son implementation et les fenêtres permettant de gérer tout ça, et te laisser pour plus tard voir le lien avec les clouds. au pire, je peux, une fois fait cela, voir ce que donne la version avec copie pour verifier si ça génère effectivement des arrets en faisant des copies completes de clouds.

jpcima commented 5 years ago

simple remarque : il s'agira de xrun en ce cas, et non simplement de discontinuité sonore.

olof29 commented 5 years ago

je suis en train de réfléchir à la question de la polyphonie de nouveau. la notion de voix qui serait réservées en mémoire à l'avance commence à se dessiner dans mon esprit.

olof29 commented 5 years ago

j'ai déposé un nouveau PR sur la gestion de la polyphonie midi

je reprends ici les explications mises dans le PR, et clos "polyphonie midi, probleme de comprehention dans la gestion des envelopes #59 " qui fait double emploi avec ici.

cette branche est assez conséquente :