Auteur Sujet: How to play sound in Shadertoy  (Lu 3607 fois)

0 Membres et 1 Invité sur ce sujet

Bonjour tout le monde,

Ca fait un bail que je suis pas passe dans le coin! J'espere que tout le monde va bien !
Je viens de decouvrir que shadertoy propose de jouer du son et je trouve ca trop cool !

Mais je ne comprends pas bien comment ca marche ! Est-ce que quelqu'un peut m'expliquer s'il vous plait ?
Pour les instruments, j'ai retrouve ce soft publie par iq y a longtemps : http://iquilezles.org/apps/soundtoy/index.html

Bonne chance a tout ceux qui vont a l'evoke ! Que la force soit avec vous !

Saorel

P.S : J'aimerais arriver a bien comprendre avant mardi 19h ... Apres il y a le hackaton shadertoy a Vancouvert, et je compte bien y participer ;-)

Mais je ne comprends pas bien comment ca marche ! Est-ce que quelqu'un peut m'expliquer s'il vous plait ?

Hm ca dépend un peu de tes connaissances en génération classique de son... donc c'est difficile de te répondre avec le détail adéquat! Mais en gros:
- Le shader de shadertoy est appelé par sample, sachant qu'il y a normalement 44000 samples/second. Donc 1 pixel = 1 sample.
- Le point d’entrée d'un shader est la fonction:
vec2 mainSound( float time )

- Si tu veux générer un simple son mono 440Hz, tu peux par exemple coder ceci:
vec2 mainSound( float time )
{
     float value = 0.5* sin(2. * 3.14 * 440. * time);
     // left = right = son a 440Hz
     return vec2(value, value);
}

Ensuite, c'est juste une variation sur ce principe, en utilisant les classiques de la synthèse audio: synthèse additive, écho, noise, filtres...etc

Dans le détail, derrière (je n'ai pas regardé leur code mais c comme ça que j'aurais fait), ce "shader de son" est encapsulé dans un pixel shader classique et ils calculent ça sur une petite surface pour permettre une synchro avec pas trop de latences avec l'image (probablement entre 20-30ms, donc environ 1320 sample, donc une texture de 132x10 pixels par exemple).

Merci beaucoup xoofx ! C'est un bon debut ! Donc pour preciser, j'ai toujours été persuader que je ne pourrais pas faire de son, mais maintenant que je sais que ca peut se coder ca m'intéresse beaucoup !

Peux tu m'en dire plus sur la synthèse additive ?

J'ai regarde le code de celui ci : ( https://www.shadertoy.com/view/ldXXDj )

Je comprends comment utiliser la function instrument( freq, time ), car elle s'appuie fortement sur soundtoy. En revanche je ne comprend pas la théorie derriere ?

Ensuite en regardant, la function mainSound() commence comme ceci :

vec2 mainSound( float time )
{
    time = mod( time, 60.0 );
   
    vec2 y = vec2(0.0);
    y += vec2(0.7,0.3)*doChannel1( time ); // main instrument
    y += vec2(0.3,0.7)*doChannel2( time ); // secondary instrument
    y *= 0.1;
   
return y;
}

Je ne comprends pas les coefficient vec2(0.7,0.3), peux tu me l'expliquer ?

Une autre question, je ne comprend pas ce qui se passe sur cette partie du code :

//----------------------------------------------------------------------------------------

#define D(a) b+=float(a);if(t>b)x=b;

//----------------------------------------------------------------------------------------

#define tint 0.144

float doChannel1( float t )
{
  float x = 0.0;
  float y = 0.0;
  float b = 0.0;
  t /= tint;

  // F2
  x = t; b = 0.0;
  D(36)D(2)D(2)D(20)D(2)D(16)D(6)D(2)D(226)
  y += instrument( 174.0, tint*(t-x) );

  // G2
  x = t; b = 0.0;
  D(53)D(208)
  y += instrument( 195.0, tint*(t-x) );

  ...

J'avoue être complètement largue ... Quelle est cette méthode D(int), d'ou viennent tous ces nombres ? Comment les determiner ?

Merci beaucoup pour ton aide xoofx, merci a ceux qui vont venir completer ce thread !


Je m'auto-repond, je poursuis mes investigations ...

Donc un petit decryptage de la fonction mainSound :

// Return vec2(left,right)
vec2 mainSound( float time )
{
    // Create a loop
    time = mod( time, 60.0 );
   
    // Init left and right to 0
    vec2 y = vec2(0.0);
    // put the 1st instrument on the left
    y += vec2(0.7,0.3)*doChannel1( time ); // main instrument
    // put the 1st instrument on the right
    y += vec2(0.3,0.7)*doChannel2( time ); // secondary instrument
// reduce the volum
    y *= 0.1;
   
return y;
}

Pour les inculte ( comme moi ) le tint correspond au delta t entre 2 notes.

Ile me reste a comprendre ce block :

  
  // F2
  x = t; b = 0.0;
  D(36)D(2)D(2)D(20)D(2)D(16)D(6)D(2)D(226)
  y += instrument( 174.0, tint*(t-x) );

Tout ce que je sais c'est que F2 est une note, mais ca ne m'avance pas beaucoup... De ce que je comprends la note F2 correspond a F3 de ce tableau ( http://en.wikipedia.org/wiki/F_(musical_note) ) et sa frequence est d'environ 174 Hz. Il me manque toujours la longue suite de D(int), ca ressemble a une frequence de frappe, mais je ne vois pas comment ca marche. Et j'ai du rater quelque chose pour le tint*(t-x)...

La fonction instrument génère un sample pour une fréquence donnée, à un temps donné: c'est à dire la valeur de l'échantillon qu'on mesurerait (avec un micro) si l'on avait vraiment joué (sur un instrument physique équivalent) la note de fréquence donnée il y a exactement tel temps.

Ce qu'il fait avec ça macro D (pour drum je pense), c'est en quelque sorte coder les coups de percussions. Les nombres en paramètres sont le nombres de beats (du tempo) entre chaque coup.
Par exemple
 D(36)D(2)D(2)D(20)D(2)D(16)D(6)D(2)D(226)
Veut dire: premier coup à 36 beats après le début, puis deux après, puis encore deux après etc...
La variable x contient le temps inférieur à t et le plus proche de t où il y a eu une percussion. (La variable est initialisée à t entre chaque note car ça fait saturer l'instrument je pense, donc en fait on l'entend pas).

Le tint permet de régler le temps que va durer chaque percussion je pense.

(j'y connais rien en musique donc je dis sûrement des conneries avec les tempos et tout ça)

Et pour es histoires de
    // put the 1st instrument on the left
    y += vec2(0.7,0.3)*doChannel1( time ); // main instrument
    // put the 1st instrument on the right
    y += vec2(0.3,0.7)*doChannel2( time ); // secondary instrument
C'est pour sortir du son stéréo. L'instrument principal s'entend mieux à gauche, l'autre à droite. Ils sont complétement symétrique là.