bjone a écrit :
...- un flux de sortie pour tout le programme donc un openStream et un closeStream en début et fin de programme, hors boucle-temps réel
|
C’est justement le rapport avec la boucle temps réel que je ne saisi pas. J’ai l’impression que, par rapport à ce que je recherche comme la génération et la modulation du son par rapport à des évènements graphiques (ex la rencontre aléatoire de 2 sphères), l’évènement sonore sort de cette boucle puisqu’une fois déclanché à partir de celle-ci, il se produit en dehors par le calcul de sa thread !?
Je dis surement des bêtises mais j’imagine dans mon cas le rôle de la Thread comme une sorte d’écouteur activé et désactivé par des évènements asynchrones (évènements physiques et graphiques)…
Par ailleurs j’ai cru comprendre qu’il fallait éviter d’ouvrir et de fermer systématiquement un stream, mais plutôt jouer sur le contenu d’un buffer circulaire qui pourrait être vide lorsqu’aucun son n’est joué …
bjone a écrit :
- ton callback de remplissage de buffer sera par la suite à remplacer par un callback de mixage avec sa petite machine à états et sa queue de buffers à mixer,
|
Mis à part ce que tu appelles la « machine à états et sa queue » j’ai 2 autres membres susceptibles de jouer ce rôle :
Code :
- bool Attack::init()
- {
- pipe = new CircBufferNoLock(sizeof(_o_)*10);// buffer circulaire
- return true;
- }
- //--------------------------------------------------------------------------------------------------------
- //...lorsque la thread audio tourne, on met les données modifiés par les évènements graphiques...
- void Attack::gui_callback(float u)
- {
- audioStruct->frequency = u;
- //---( ! ) error C228 left of 'writeBuffer' must have a class/strut/inion !?
- // pipe.writeBuffer(&_o_, sizeof(Attack_o));
- }
|
Que veux tu dire par threading, car le callback c’est bien l’aboutissement d’une thread non ?
bjone a écrit :
-Dans ce cas il consisterai je pense à un thread de mixage qui fourni qui pousse un buffer en queue d'attente, et le callback passé à RtAudio qui vienne chercher les buffers mixés en queue.
|
Dit comme ça, je n’demande pas mieux ;-)
bjone a écrit :
.
- Donc revois ta structure générale, parceque là c'est pas bon.
|
Pour l’instant la partie graphique et physique tourne bien. J’ai pensée à une classe principale (statique) pour les manip globales (gestion des canaux, effets) et à une classe dynamique représentant du son singulier. C’est le code du STK lui-même et la notion de thread qui me perdent encore.
Pour être plus précis sur ma structure générale j’ai:
Define.h // contient des déclaration d’entêtes et descriptions de structures utilisées ds les classes statiques et dynamiques
Une classe principale Engine déclarée dans le main, qui instancie les classes graphiques, physique et sonore dont les membres seront appelés dans une boucle glut :
Code :
- glutDisplayFunc(RenderCallback_1);
- void RenderCallback_1()
- {
- if (gScene && !bPause)
- RunPhysics();
- // Clear buffers
- glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
- ProcessKeys();
- GraphicCORE::updateBUTTONSAndSLIDERS();
- PhysicCORE::updateCAMERA();
- PhysicCORE::updateSHAPES();
- PhysicCORE::updateLINES();
- PhysicCORE::updateSTICKERS();
- RenderScene(bShadows);
- if( gSelectedActor != NULL ){
- NxVec3 V= gSelectedActor->getGlobalPosition();
- GraphicCORE::drawAXIS(V.x, V.y, V.z, 10.0F,8.0F,10.0F, 10.0F,6.0F,10.0F,"<X>","<Y>","<Z>" );
- }
- DisplayText();
- gPerfRenderer.render(gScene->readProfileData(true), glutGet(GLUT_WINDOW_WIDTH), glutGet(GLUT_WINDOW_HEIGHT));
- glutSwapBuffers();
- //----------------------
- //SoundCORE::render();
- }
|
Comme je n’ai pas pu intégrer toutes mes classes respectives (image, physique…), certaines fonctions sont restées dans le main comme la boucle glut ou le gestionnaire de collisions physiques …
L'articulation des 2 classes, statique et dynamiques me semblait cohérentes jusqu'à ce qu'apparaissent les threads...d'ailleurs
on m'a conseillé de mettre
bjone a écrit :
my_zuper_audiomixing_engine.start(); // openStream
glutReshapeFunc(ReshapeCallback_1);
glutDisplayFunc(RenderCallback_1);
my_zuper_audiomixing_engine.close();
}
|
En imaginant que le Stream serait ouvert/fermer indépendamment, my_zuper_audiomixing_engine…() pourrait remplir le buffer de nouveaux paramètres audio ?
bjone a écrit :
Quand tu sais que tu dois avoir un bruit, tu le mets en queue d'attente,
|
A moins qu’il y est un exemple dans le STK je vais faire qlq recherches mais si tu as exemple de queue d'attente ...
bjone a écrit :
et au prochain callback tu commence à le mixer avec les autres dans le buffer final qui sera passés aux dac par RtAudio.
|
…si j’arrive au premier callback ;-)
bjone a écrit :
... je te conseillerai OpenAl ou autre une lib audio de plus haut-niveau pour avoir un truc qui te guide.
|
Je pensais que c'était plutôt pour jouer des sons (sampling) que de la synthèse sonore où tu travailles vraiment son signal...
bjone a écrit :
Même si par après pour ta culture générale tu peux très bien revenir sur un mixage complètement maison utilisant une API bas-niveau.
|
En fait, j'avais pensé que pour générer un son particulier, par ex une onde faite de plusieurs sinusoïdes modulées par une série de variables(ex : liste de positions) ce serait la meilleur alternative. Maintenant, je sais que ça me dépasse totalement cette histoire, d’autant plus que je commence le c++ très tard, mais bon je reste fasciné par le bas niveau et le plus grand degré de liberté qu'on peut en espérer. De plus, à défaut d'avoir pu suivre des cours, ce sont des gens comme toi qui permettent à d'autre de toucher des choses qu'ils n'aurait jamais eu l'occasion ou le courage...et blablabla, enfin voilà, en tout cas ton analyse m’éclaircit bien les idées et si mes précisions change ta vision du prob … poursuivons