IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

 C Discussion :

Besoin d'un petit coup de main pour corriger une sinusoIde


Sujet :

C

  1. #1
    Expert éminent sénior
    Avatar de Jipété
    Profil pro
    Inscrit en
    Juillet 2006
    Messages
    10 747
    Détails du profil
    Informations personnelles :
    Localisation : France, Hérault (Languedoc Roussillon)

    Informations forums :
    Inscription : Juillet 2006
    Messages : 10 747
    Points : 15 166
    Points
    15 166
    Par défaut Besoin d'un petit coup de main pour corriger une sinusoIde
    Bonjour

    et tous mes meilleurs vœux.

    Avant toute chose, je ne suis pas matheux...

    Ceci étant dit, j'ai récemment trouvé cette page web d'où j'en ai tiré ce code,
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
     
    /* pour compil linux : gcc montest.c -lm -o montest */
     
    #include <stdio.h>
    #include <math.h>
     
    int main()
    {
    	int x;
    	int RunningSampleIndex;
    	int SamplingFrequency;
    	float Frequency;
    	float WavePeriod;
    	float angle;
    	float Volume;
    	float SampleValue;
    	float tSine;
     
    	Frequency=500.0;
    	Volume=0.5;
    	WavePeriod=1/Frequency; // 0.002
    	RunningSampleIndex=0;
     
        for(x=0; x<44100; x+=1)
        {
    //		fprintf (stdout,   "RunningSampleIndex : %3llu \n", RunningSampleIndex);
    		angle=2.0f*M_PI*(RunningSampleIndex / WavePeriod);
    //        fprintf (stdout,   "angle : %f \n", angle);
    //		SampleValue=sinf(angle) * Volume;
    //        fprintf (stdout,   "SpVal : %f \n", SampleValue);
    		tSine += 2.0f*M_PI/WavePeriod; // pourquoi ...Pi32*1.0f/WavePeriod ?
    //        fprintf (stdout,   "tSine : %f \n", tSine);
    		SampleValue = sinf(tSine) * Volume;
            fprintf (stdout,   "SpVal : %10.6f \n", SampleValue);
    		RunningSampleIndex+=1;
    //        fprintf (stdout,   "\n");
        }
     
        return(0);
    }
    (j'ai laissé les commentaires pour montrer par où je suis passé, et les décalages d'alignements sont le fait de l'éditeur du forum)

    Est-ce que quelqu'un peut me dire si mon interprétation est correcte ?
    Car je trouve qu'il n'y a pas beaucoup de valeurs quand on regarde une demi-période comme par exemple les dernières lignes de la fin de l'exécution du prog :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    ...
    SpVal :  -0.232851 
    SpVal :   0.102324 
    SpVal :   0.390616 
    SpVal :   0.499933 // tout en haut
    SpVal :   0.380189 
    SpVal :   0.086248 
    SpVal :  -0.247211 
    SpVal :  -0.467401 
    SpVal :  -0.473435 // tout en bas
    SpVal :  -0.262548 
    SpVal :   0.068635
    Si je passe le volume à 0.99, ça donne ça :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    SpVal :  -0.461045 
    SpVal :   0.202601 
    SpVal :   0.773419 
    SpVal :   0.989867 // tout en haut
    SpVal :   0.752774 
    SpVal :   0.170770 
    SpVal :  -0.489478 
    SpVal :  -0.925454 
    SpVal :  -0.937401 // tout en bas
    SpVal :  -0.519845 
    SpVal :   0.135896
    Les écarts de volume sont plus élevés, mais je trouve qu'il n'y a pas beaucoup de samples d'une période à l'autre : normal ? Pas normal ?

    Une ligne que je n'ai pas bien su traduire, dans l'article : tSine += 2.0f*Pi32*1.0f/(float)WavePeriod;. D'abord je n'ai pas trouvé Pi32 (et en cherchant avec ggl je me suis retrouvé soit sur du Pic soit avec des images chaudes, pas que je les rejette mais ce n'était pas le sujet) alors je l'ai remplacé par M_PI, et je n'ai pas compris ensuite à quoi servait *1.0f alors je l'ai viré.
    Bien ? Pas bien ?

    Gramd merci par avance,
    Il a à vivre sa vie comme ça et il est mûr sur ce mur se creusant la tête : peutêtre qu'il peut être sûr, etc.
    Oui, je milite pour l'orthographe et le respect du trait d'union à l'impératif.
    Après avoir posté, relisez-vous ! Et en cas d'erreur ou d'oubli, il existe un bouton « Modifier », à utiliser sans modération
    On a des lois pour protéger les remboursements aux faiseurs d’argent. On n’en a pas pour empêcher un être humain de mourir de misère.
    Mes 2 cts,
    --
    jp

  2. #2
    Expert éminent
    Homme Profil pro
    Ingénieur développement matériel électronique
    Inscrit en
    Décembre 2015
    Messages
    1 568
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 61
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Ingénieur développement matériel électronique
    Secteur : High Tech - Électronique et micro-électronique

    Informations forums :
    Inscription : Décembre 2015
    Messages : 1 568
    Points : 7 658
    Points
    7 658
    Par défaut
    Bonjour,

    Peut-être devrais-tu commencer par expliquer ce que tu cherches à faire.

    Ce que le code fait:
    ligne 27, on calcule un angle mais on ne s'en sert jamais!
    ligne 29, on fait évolue tSine (donc l'angle) en y ajoutant 2*pi/(1/500.), autrement on ajoute 1000pi à l'angle ce qui ne fait que produire du bruit.
    De plus tous les calculs sont fait en float au lieu de double, le float fait gagner quelque octets en mémoire mais dégrade fortement la précision sans être plus plus rapide, il faut toujours y préférer le double.

  3. #3
    Expert éminent sénior
    Avatar de Jipété
    Profil pro
    Inscrit en
    Juillet 2006
    Messages
    10 747
    Détails du profil
    Informations personnelles :
    Localisation : France, Hérault (Languedoc Roussillon)

    Informations forums :
    Inscription : Juillet 2006
    Messages : 10 747
    Points : 15 166
    Points
    15 166
    Par défaut
    Citation Envoyé par dalfab Voir le message
    Peut-être devrais-tu commencer par expliquer ce que tu cherches à faire.
    Ben, récupérer les données de la sinusoïde pour voir si je peux transposer le code en Pascal et de là en Lazarus pour la dessiner.

    Citation Envoyé par dalfab Voir le message
    Ce que le code fait:
    ligne 27, on calcule un angle mais on ne s'en sert jamais!
    Séquelle de la première lecture de la page.

    Citation Envoyé par dalfab Voir le message
    ligne 29, on fait évolue tSine (donc l'angle) en y ajoutant 2*pi/(1/500.), autrement on ajoute 1000pi à l'angle ce qui ne fait que produire du bruit.
    Pas compris, d'autant plus que cette ligne 29 est en commentaire,

    Citation Envoyé par dalfab Voir le message
    De plus tous les calculs sont fait en float au lieu de double, le float fait gagner quelque octets en mémoire mais dégrade fortement la précision sans être plus plus rapide, il faut toujours y préférer le double.
    C'est d'origine, et je propose de voir ça après.

    Merci pour le retour.
    Il a à vivre sa vie comme ça et il est mûr sur ce mur se creusant la tête : peutêtre qu'il peut être sûr, etc.
    Oui, je milite pour l'orthographe et le respect du trait d'union à l'impératif.
    Après avoir posté, relisez-vous ! Et en cas d'erreur ou d'oubli, il existe un bouton « Modifier », à utiliser sans modération
    On a des lois pour protéger les remboursements aux faiseurs d’argent. On n’en a pas pour empêcher un être humain de mourir de misère.
    Mes 2 cts,
    --
    jp

  4. #4
    Expert éminent
    Homme Profil pro
    Ingénieur développement matériel électronique
    Inscrit en
    Décembre 2015
    Messages
    1 568
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 61
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Ingénieur développement matériel électronique
    Secteur : High Tech - Électronique et micro-électronique

    Informations forums :
    Inscription : Décembre 2015
    Messages : 1 568
    Points : 7 658
    Points
    7 658
    Par défaut
    Voilà un code qui calcule une période d'un sinus
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    #include <stdio.h>
    #include <math.h>
     
    int main()
    {
        double  PasEnDegres = 1.;
        double  Volume = 100.;
        for ( int i = 0 ; i <= 360 ; ++i ) {
            double  angle_degres = i * PasEnDegres;
            double  angle_radians = angle_degres * (2. * M_PI / 360.);
            double  sinus = sin( angle_radians );  // la fonction sin() reçoit toujours des radians
            printf( "sinus(%f degres) = sinus(%f radians) = %f" , angle_degres , angle_radian, sinus );
            double  avec_volume = sinus * Volume;
            printf( ", avec volume : %f\n" , avec_volume );
        }
    }

  5. #5
    Expert éminent sénior
    Avatar de Jipété
    Profil pro
    Inscrit en
    Juillet 2006
    Messages
    10 747
    Détails du profil
    Informations personnelles :
    Localisation : France, Hérault (Languedoc Roussillon)

    Informations forums :
    Inscription : Juillet 2006
    Messages : 10 747
    Points : 15 166
    Points
    15 166
    Par défaut
    Bonsoir,

    Citation Envoyé par dalfab Voir le message
    Voilà un code qui calcule une période d'un sinus
    Merci, c'est très gentil à toi mais ça n'est pas ce que je demandais, qui est, je le rappelle, de savoir si le code que j'ai posté est correct ou pas, indépendamment de la ligne qui ne sert à rien.

    Ceci étant dit, j'aurai quand même une question concernant ton code : à quoi sert cette variable PasEnDegres à laquelle tu assignes la valeur 1. et qui n'en bouge plus ?
    Tu ne pouvais pas simplement écrire double angle_degres = i * 1.; ? On aurait compris que tu forçais un cast de i integer vers double.
    Alors qu'avec cette histoire PasEnDegres, je ne sais pas si tu parles d'un écart (StepsInDegrees) ou d'une information (NotInDegrees), tu vois le truc ?

    D'autant plus que l'avant-dernière ligne memo.Lines.Add('SpVal : %10.6f', [SampleValue]);, si elle compile en Pascal et s'exécute, me retourne une avalanche de 0.000000...
    En C c'est fprintf (stdout, "SpVal : %10.6f \n", SampleValue); précédé de SampleValue = sinf(tSine) * Volume; et c'est quoi ce sinf ? Ne l'ayant pas en Pascal, je l'ai remplacé par sin tout court, mais c'est ça qui doit coincer.
    Il a à vivre sa vie comme ça et il est mûr sur ce mur se creusant la tête : peutêtre qu'il peut être sûr, etc.
    Oui, je milite pour l'orthographe et le respect du trait d'union à l'impératif.
    Après avoir posté, relisez-vous ! Et en cas d'erreur ou d'oubli, il existe un bouton « Modifier », à utiliser sans modération
    On a des lois pour protéger les remboursements aux faiseurs d’argent. On n’en a pas pour empêcher un être humain de mourir de misère.
    Mes 2 cts,
    --
    jp

  6. #6
    Expert éminent sénior
    Homme Profil pro
    Analyste/ Programmeur
    Inscrit en
    Juillet 2013
    Messages
    4 632
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Analyste/ Programmeur

    Informations forums :
    Inscription : Juillet 2013
    Messages : 4 632
    Points : 10 560
    Points
    10 560
    Par défaut
    Citation Envoyé par Jipété Voir le message
    c'est quoi ce sinf ?
    Regarde les include <cmath> (math.h), lien cplusplus.com en anglais

    Effectivement c'est assez subtil, mais il n'y a que sin sur la page documentation
    C'est depuis C99 (il faut cliquer sur "l'onglet") double sin (double x); float sinf (float x); long double sinl (long double x);.
    Donc sans surprise, sinf est le sinus avec des float

    Sinon ton code c'est du brouillon et on ne comprend rien
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
            angle=2.0f*M_PI*(RunningSampleIndex / WavePeriod);
    //      ...
            RunningSampleIndex+=1;
    Ce code ne sert à rien.

    Le seul code valable est (la variable SampleValue ne sert à rien comme la majorité soit dit en passant)
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
            tSine += 2.0f*M_PI/WavePeriod;
            SampleValue = sinf(tSine) * Volume;
            fprintf (stdout,   "SpVal : %10.6f \n", SampleValue);
    Que tu vas faire varier 44100 fois.
    Et comme l'a dit @dalfab, avec WavePeriod = 1 / Frequency = 1 / 500 = 0.002, alors tu ajoutes à chaque tour (2 * Pi) / (1 / 500) = 500 * 2 * Pi = 1000 * Pi.
    Donc 1000 * Pi RADIANs.

    Rien de + à ajouter sans + d'explications


    Citation Envoyé par Jipété Voir le message
    Alors qu'avec cette histoire PasEnDegres, je ne sais pas si tu parles d'un écart (StepsInDegrees) ou d'une information (NotInDegrees), tu vois le truc ?
    IntervalInDegrees est + approprié

  7. #7
    Expert éminent sénior
    Avatar de Sve@r
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Février 2006
    Messages
    12 698
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Oise (Picardie)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Février 2006
    Messages : 12 698
    Points : 30 997
    Points
    30 997
    Billets dans le blog
    1
    Par défaut
    Bonjour
    Citation Envoyé par Jipété Voir le message
    Ceci étant dit, j'aurai quand même une question concernant ton code : à quoi sert cette variable PasEnDegres à laquelle tu assignes la valeur 1. et qui n'en bouge plus ?
    C'est l'écart entre l'angle X et l'angle Y suivant. Et nommé à la française donc équivalent à un step en anglais.

    Citation Envoyé par Jipété Voir le message
    Tu ne pouvais pas simplement écrire double angle_degres = i * 1.; ? On aurait compris que tu forçais un cast de i integer vers double.
    Si on veut forcer un cast de i en double on l'écrit en notation cast => double angle_degres = (double)i (cast automatique lors d'une affectation => double angle_degres = i marche tout aussi bien).

    Citation Envoyé par Jipété Voir le message
    récupérer les données de la sinusoïde pour voir si je peux transposer le code en Pascal et de là en Lazarus pour la dessiner.
    Citation Envoyé par Jipété Voir le message
    Merci, c'est très gentil à toi mais ça n'est pas ce que je demandais, qui est, je le rappelle, de savoir si le code que j'ai posté est correct ou pas, indépendamment de la ligne qui ne sert à rien.
    Ben si le code de dalfab fait la même chose en plus simple que ton code d'origine (code qui reste assez incompréhensible et que beaucoup ici critiquent en raison de certains calculs inutiles) pourquoi ne pas remplacer le tien par le sien? Suis allé voir la page que tu montres mais c'est un lien youtube de 2h en anglais donc j'ai abandonné (une vidéo c'est pas un bon support pour un cours)
    Mon Tutoriel sur la programmation «Python»
    Mon Tutoriel sur la programmation «Shell»
    Sinon il y en a pleins d'autres. N'oubliez pas non plus les différentes faq disponibles sur ce site
    Et on poste ses codes entre balises [code] et [/code]

  8. #8
    Expert éminent sénior
    Avatar de Jipété
    Profil pro
    Inscrit en
    Juillet 2006
    Messages
    10 747
    Détails du profil
    Informations personnelles :
    Localisation : France, Hérault (Languedoc Roussillon)

    Informations forums :
    Inscription : Juillet 2006
    Messages : 10 747
    Points : 15 166
    Points
    15 166
    Par défaut
    Citation Envoyé par foetus Voir le message
    Donc sans surprise, sinf est le sinus avec des float
    Coucou,
    Ben ça ne m'est pas venu à l'esprit parce qu'en Pascal on met le type devant, ça aurait donc donné fSin.

    Citation Envoyé par foetus Voir le message
    Sinon ton code c'est du brouillon et on ne comprend rien
    J'ai bien écrit que j'avais essayé de retranscrire ce que l'autre sur son site a rédigé comme un roman et des fois c'est tendu de passer du roman au code, hé oui : il manque le pseudocode au milieu...

    Citation Envoyé par foetus Voir le message
    IntervalInDegrees est + approprié
    Merci pour ce point capital !

    Citation Envoyé par Sve@r Voir le message
    Ben si le code de dalfab fait la même chose en plus simple que ton code d'origine (code qui reste assez incompréhensible et que beaucoup ici critiquent en raison de certains calculs inutiles) pourquoi ne pas remplacer le tien par le sien?
    Pour (essayer de) comprendre.
    Par exemple, en ce moment je me tape un pdf de 1991 écrit et publié par IBM et Microsoft (cherchez "multimedia programming interface and data specifications 1.0") et... il y a des erreurs dedans, dans la section WAVE (je n'ai pas lu les autres) !
    Genre l'oubli d'une ligne dans la définition du WAVE chunk, ou des oublis dans les exemples (4 données expliquées sur les 6 présentées et pas dans l'ordre de l'exemple, pour les 2 oubliées, demerdenzizich, ce qui revient à fouiller partout puis examiner à l'éditeur hexa le contenu de fichiers, au bout d'un certain temps on voit le bout du tunnel.
    Citation Envoyé par Sve@r Voir le message
    Suis allé voir la page que tu montres mais c'est un lien youtube de 2h en anglais donc j'ai abandonné (une vidéo c'est pas un bon support pour un cours)

    Il suffisait de descendre dans la page, sous la vidéo, et il y a le texte et des bouts de code : Generating a sine-wave test tone.

    En fait, ce qui m'a attiré dans ce code/cette page, c'est ça :
    Citation Envoyé par site cité
    When you change the frequency with the current code, you'll end up with an artifact. To combat this, you need ...
    que je n'avais jamais vu ailleurs, et j'aurais aimé creuser cet aspect des choses.

    Merci et bonne journée, je verrai tout ça un peu plus tard.
    Il a à vivre sa vie comme ça et il est mûr sur ce mur se creusant la tête : peutêtre qu'il peut être sûr, etc.
    Oui, je milite pour l'orthographe et le respect du trait d'union à l'impératif.
    Après avoir posté, relisez-vous ! Et en cas d'erreur ou d'oubli, il existe un bouton « Modifier », à utiliser sans modération
    On a des lois pour protéger les remboursements aux faiseurs d’argent. On n’en a pas pour empêcher un être humain de mourir de misère.
    Mes 2 cts,
    --
    jp

  9. #9
    Membre expérimenté
    Avatar de sambia39
    Homme Profil pro
    No Comment
    Inscrit en
    Mai 2010
    Messages
    543
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Loiret (Centre)

    Informations professionnelles :
    Activité : No Comment
    Secteur : High Tech - Matériel informatique

    Informations forums :
    Inscription : Mai 2010
    Messages : 543
    Points : 1 745
    Points
    1 745
    Par défaut
    Bonjour,

    Si je comprends bien, votre code consiste à générer un signal sinusoïdal à l'aide d'une boucle "for" pour une itération de valeur "44100" ? c'est-à-dire une résolution de 44100 Hz, (n'est-ce pas ?) .
    Ainsi sans trop m'avancer; votre boucle "for" génère le signal sinusoïdal, et vous calculez l'angle du signal, "tSine" et la valeur de l'échantillon en utilisant la fonction sin. Puis vous incrémentez "RunningSampleIndex" de 1 afin que votre valeur d'échantillon ait plusieurs valeurs dans une demi-période, car la fonction sinus oscille entre 1 et -1. Donc, si vous augmentez le volume, le niveau sonore va augmenter et le signal sera fort ce qui entraîne des différences de volume plus importantes car, le volume est défini par une valeur initiale de 0.5 ; Il n'y aura donc pas beaucoup d'échantillons d'une période à l'autre.

    Il est clair ici; que votre intention ou l'intention de celui qui a implémenté le code source original est donc de génère un signal sinusoïdal à l'aide d'une boucle "for" pour une itération qui équivaut à valeur "44100hz". et si vous augmentez le volume, le niveau sonore augmentera et le signal sera plus fort, entraînant une différence de volume plus importante. Ainsi; il n'y aura pas beaucoup d'échantillons d'une période à l'autre.

    Et oui ; l’écart que vous décrivez est plus grande même avec un volume défini avec une valeur de 0.99. Vous obtiendrez toujours (façon de parlé) le même résultats. C'est a dire; pas beaucoup d'échantillons d'une période à l'autre du a l'itération (fréquence) 44100Hz; mais en revanche, cette itération est assez pour générer un signal. Au finale si vous souhaitez avoir plus de samples d'une période à l'autre, vous devez augmenter le nombre de fois que la boucle for itère en plus claire vous devez opté pour une fréquence beaucoup plus élevé (clairement supérieur a 44100) ce qui vous permettras d’obtenir plus de samples d'une période à l'autre.

    Quant à Pi32 c'est une constante qui est équivalente à M_PI, et le 1.0f est utilisé pour convertir le résultat de l'opération en un float. Pas d'inquiétude, vous pouvez remplacer Pi32 par M_PI et supprimer le 1.0f pour obtenir le même résultat.
    En conclusion sans trop m'avancer dans les détails de l'implémentation et autres bidules, votre approche est correcte et votre conclusion l'est aussi; a condition ou dans l'unique but d'obtenir ou générer un signal qui va contenir un certains nombres de sample pour du son audible(dans un spectre de son audible) ou pour la composition d'un son (de mon point de vue et peut être que je me trompe).
    à bientôt
    Celui qui peut, agit. Celui qui ne peut pas, enseigne.
    Il y a deux sortes de savants: les spécialistes, qui connaissent tout sur rien,
    et les philosophes, qui ne connaissent rien sur tout.
    George Bernard Shaw

  10. #10
    Expert éminent sénior
    Avatar de Jipété
    Profil pro
    Inscrit en
    Juillet 2006
    Messages
    10 747
    Détails du profil
    Informations personnelles :
    Localisation : France, Hérault (Languedoc Roussillon)

    Informations forums :
    Inscription : Juillet 2006
    Messages : 10 747
    Points : 15 166
    Points
    15 166
    Par défaut
    Citation Envoyé par sambia39 Voir le message
    Si je comprends bien, votre code consiste à générer un signal sinusoïdal à l'aide d'une boucle "for" pour une itération de valeur "44100" ? c'est-à-dire une résolution de 44100 Hz, (n'est-ce pas ?).
    C'est tout à fait ça.

    C'est vrai que j'ai été surpris par la faible quantité d'échantillons, mais si on met dit que c'est comme ça et que ça fonctionne bien ainsi, alors ma foi, pourquoi pas ?
    Merci pour l'explication.
    Il a à vivre sa vie comme ça et il est mûr sur ce mur se creusant la tête : peutêtre qu'il peut être sûr, etc.
    Oui, je milite pour l'orthographe et le respect du trait d'union à l'impératif.
    Après avoir posté, relisez-vous ! Et en cas d'erreur ou d'oubli, il existe un bouton « Modifier », à utiliser sans modération
    On a des lois pour protéger les remboursements aux faiseurs d’argent. On n’en a pas pour empêcher un être humain de mourir de misère.
    Mes 2 cts,
    --
    jp

  11. #11
    Expert éminent sénior
    Homme Profil pro
    Analyste/ Programmeur
    Inscrit en
    Juillet 2013
    Messages
    4 632
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Analyste/ Programmeur

    Informations forums :
    Inscription : Juillet 2013
    Messages : 4 632
    Points : 10 560
    Points
    10 560
    Par défaut
    En écoutant la vidéo, c'est juste 1 "game jam"
    Et si je comprends bien, les gars font 1 moteur audio (basé sur/ à partir de/ qu'ils testent avec/ ???) la courbe sinus : sine wave, page wikipedia en anglais
    J'ai mis en commentaire dans le code la formule.
    Et en gros le jour précédent (jour 8), c'était 1 signal carré (dans le code "Old Version")
    Ce jour-ci (jour 9), il met à jour avec la formule du sinus (dans le code "New Version")
    Et pour l'artefact, c'est le code qui est mauvais (je n'ai pas été au bout) ... ce qui est normal puisqu'il est cours d'implémentation, mais il y a 1 histoire de double-buffer audio mal réglé.

    Voici le code "brut de fonderie" de la vidéo, peut-être s'amuser avec la variable Region1SampleCount.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    #include <stdio.h>
    #include <stdint.h>
    #include <stdlib.h>
    #include <math.h>
     
    typedef float    real32;
    typedef int32_t  DWORD;
    typedef int16_t  int16;
    typedef uint32_t uint32;
     
    #define Region1SampleCount 100
    #define M_PI                 3.14159265359f
     
    int main()
    {
        int SamplesPerSecond      = 48000;
        int ToneHz                = 256;
        int16 TonerVolume         = 3000;
        uint32 RunningSampleIndex = 0;
        int SquareWavePeriod      = SamplesPerSecond/ToneHz;
        int WavePeriod            = SamplesPerSecond/ToneHz;
        int HalfSquareWavePeriod  = SquareWavePeriod/2;
        int HalfWavePeriod        = WavePeriod/2;
        int BytesPerSample        = sizeof(int16)*2;
        int SecondaryBufferSize   = SamplesPerSecond*BytesPerSample;
     
     
    //  Sine wave : A * sin(2 * pi * F * t + phase)
    //  A, amplitude, the peak deviation of the function from zero.
    //  f, ordinary frequency, the number of oscillations (cycles) that occur each second of time
    //  phase, specifies (in radians) where in its cycle the oscillation is at t = 0.
     
        printf("Old Version:\n");
     
        for(DWORD SampleIndex=-Region1SampleCount; SampleIndex < Region1SampleCount; ++SampleIndex) {
            int16 SampleValue = (((RunningSampleIndex / HalfSquareWavePeriod) % 2 )? TonerVolume: -TonerVolume);
     
            ++RunningSampleIndex;
     
            printf("% 4d: %6d\n", (SampleIndex + Region1SampleCount), SampleValue);
        }
     
     
        printf("\n\nNew Version:\n");
     
        RunningSampleIndex = 0;
     
        for(DWORD SampleIndex=-Region1SampleCount; SampleIndex < Region1SampleCount; ++SampleIndex) {
            real32 t           = 2.0f*M_PI*(real32) RunningSampleIndex / (real32) WavePeriod;
            real32 SineValue   = sinf(t);
            int16  SampleValue = (int16) (SineValue * TonerVolume);
     
            ++RunningSampleIndex;
     
            printf("% 4d: %6d\n", (SampleIndex + Region1SampleCount), SampleValue);
        }
     
     
        return EXIT_SUCCESS;
    }
    Édit : mis à jour de l'affichage de SampleIndex pour qui commence à 0 et remise à zéro de RunningSampleIndex pour la nouvelle version

  12. #12
    Membre éprouvé
    Femme Profil pro
    ..
    Inscrit en
    Décembre 2019
    Messages
    567
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Âge : 94
    Localisation : Autre

    Informations professionnelles :
    Activité : ..

    Informations forums :
    Inscription : Décembre 2019
    Messages : 567
    Points : 1 265
    Points
    1 265
    Par défaut
    Salut,

    En vrac

    M_PI existe déjà dans la libC, il faut juste définir _USE_MATH_DEFINES avant d'inclure math.h pour le rendre accessible.
    La formule permet de moduler la porteuse (ici la fonction sinus) en fréquence et en amplitude (attention c'est différent du volume).
    Le 1.0f qui turlupine doit être rattaché à waveperiod est doit être lu comme (1.0f/période) autrement dit c'est l'inverse de la période, c'est-à-dire la fréquence.
    Le nombre de valeurs par période est égale à la division de la fréquence d'échantillonnage par la fréquence du signal.

  13. #13
    Expert éminent sénior
    Avatar de Jipété
    Profil pro
    Inscrit en
    Juillet 2006
    Messages
    10 747
    Détails du profil
    Informations personnelles :
    Localisation : France, Hérault (Languedoc Roussillon)

    Informations forums :
    Inscription : Juillet 2006
    Messages : 10 747
    Points : 15 166
    Points
    15 166
    Par défaut
    Yep !

    Citation Envoyé par kaitlyn Voir le message
    La formule permet de moduler la porteuse (ici la fonction sinus) en fréquence et en amplitude (attention c'est différent du volume).
    Précise ta pensée, merci.

    Sinon, juste pour rire,
    Citation Envoyé par kaitlyn Voir le message
    La formule permet de moduler la porteuse en fréquence et en amplitude
    On fait de la radio, là ? Alors ce "et" m'ennuie : on module une porteuse en fréquence ou en amplitude, je n'ai jamais entendu parler des deux ensemble,

    Quoique, en y réfléchissant bien, je me dis "après tout pourquoi pas ?"
    Faudrait que je révise mes classiques...
    Il a à vivre sa vie comme ça et il est mûr sur ce mur se creusant la tête : peutêtre qu'il peut être sûr, etc.
    Oui, je milite pour l'orthographe et le respect du trait d'union à l'impératif.
    Après avoir posté, relisez-vous ! Et en cas d'erreur ou d'oubli, il existe un bouton « Modifier », à utiliser sans modération
    On a des lois pour protéger les remboursements aux faiseurs d’argent. On n’en a pas pour empêcher un être humain de mourir de misère.
    Mes 2 cts,
    --
    jp

  14. #14
    Expert éminent sénior
    Avatar de Jipété
    Profil pro
    Inscrit en
    Juillet 2006
    Messages
    10 747
    Détails du profil
    Informations personnelles :
    Localisation : France, Hérault (Languedoc Roussillon)

    Informations forums :
    Inscription : Juillet 2006
    Messages : 10 747
    Points : 15 166
    Points
    15 166
    Par défaut
    @foetus : Tu ne nous as pas dit quels étaient tes résultats :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    Old Version:
    -100  -3000
    ...  bascule à -7 de -3000 à  3000
      -1   3000
       0   3000
       1   3000
    ...  bascule à 86 de  3000 à -3000
      99  -3000
     
    New Version:
    -100   1269 on monte
     -66   2999 et on redescend
     -20     50 on continue à descendre
     -19    -50
      27  -2999 on touche le fond 
      99   2233 et on est remonté
    Tu as eu ça chez toi ?


    Citation Envoyé par foetus Voir le message
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    #include <math.h> 
     
    // #define M_PI                 3.14159265359f déjà défini dans math.h
    Bon, je regarderai le reste du code plus tard, grand merci à toi, mais quand même un bout qui m'a fait rire :
    Citation Envoyé par foetus Voir le message
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    int16 SampleValue = (((RunningSampleIndex / HalfSquareWavePeriod) % 2 )? TonerVolume: -TonerVolume);
    Tu manages la quantité de poudre de ton imprimante laser ?
    Il a à vivre sa vie comme ça et il est mûr sur ce mur se creusant la tête : peutêtre qu'il peut être sûr, etc.
    Oui, je milite pour l'orthographe et le respect du trait d'union à l'impératif.
    Après avoir posté, relisez-vous ! Et en cas d'erreur ou d'oubli, il existe un bouton « Modifier », à utiliser sans modération
    On a des lois pour protéger les remboursements aux faiseurs d’argent. On n’en a pas pour empêcher un être humain de mourir de misère.
    Mes 2 cts,
    --
    jp

  15. #15
    Membre éprouvé
    Femme Profil pro
    ..
    Inscrit en
    Décembre 2019
    Messages
    567
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Âge : 94
    Localisation : Autre

    Informations professionnelles :
    Activité : ..

    Informations forums :
    Inscription : Décembre 2019
    Messages : 567
    Points : 1 265
    Points
    1 265
    Par défaut
    Contrairement à l’amplitude, le volume est subjectif. D'ailleurs il change avec la fréquence.
    Et oui oui c'est bien un "et", sauf que là on ne fait pas de la radio, mais fondamentalement c'est pas très différent.
    Après j’imagine que tu dis ça parce que tu es habitué à France Inter sur ton poste à galène

  16. #16
    Membre éprouvé
    Femme Profil pro
    ..
    Inscrit en
    Décembre 2019
    Messages
    567
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Âge : 94
    Localisation : Autre

    Informations professionnelles :
    Activité : ..

    Informations forums :
    Inscription : Décembre 2019
    Messages : 567
    Points : 1 265
    Points
    1 265
    Par défaut
    J'ai regardé un peu ta vidéo, voici une autre ressource qui probablement t'intéressera
    https://www3.nd.edu/~dthain/courses/...ll2013/wavfile

  17. #17
    Expert éminent sénior
    Homme Profil pro
    Analyste/ Programmeur
    Inscrit en
    Juillet 2013
    Messages
    4 632
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Analyste/ Programmeur

    Informations forums :
    Inscription : Juillet 2013
    Messages : 4 632
    Points : 10 560
    Points
    10 560
    Par défaut
    Citation Envoyé par Jipété Voir le message
    @foetus : Tu ne nous as pas dit quels étaient tes résultats
    Édit : tu peux utiliser 1 compilateur en ligne C/ C++ comme onlinegdb (<- lien, il y a 1 liste déroulante à droite pour choisir son langage)
    Sinon sous Linux/ Mac c'est gcc source.c -o exec -Wall; ./exec

    Effectivement, mais je pense que le gars veut tester son moteur audio avec 1 maximum de "fréquences" ou de "volumes" (disons trucmuche)

    Donc pour cela, trucmuche doit varier de -3000 à 3000, puis de 3000 à -3000 (me demande pas pourquoi 3000 ... qui est TonerVolume)
    Édit : avec le code que j'ai publié provenant de la vidéo, il faut 92-93 valeurs pour aller de -3000 à 3000 (ou inversement)

    Édit : 92-93 vient de (SamplesPerSecond (48 000) / ToneHz (256)) / 2 ou SamplesPerSecond (48 000) / (2 * ToneHz (256)) = 93.75
    Mais dans la nouvelle version (avec le sinus), le gars n'utilise pas la variable HalfWavePeriod (qui divise par 2) parce que le 2 vient de la formule du sinus : A * sin(2 * pi * F * t + phase).
    Donc l'amplitude c'est TonerVolume (pourquoi ?) et la fréquence c'est SamplesPerSecond (48 000) / ToneHz (256) (pourquoi ?)
    Mais TonerVolume = 93.75 * 32 bizarre

    Et au lieu de faire du code style
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    #include <stdio.h>
    #include <stdint.h>
    #include <stdlib.h>
     
    #define Region1SampleCount 160
    #define Step                93.75f
     
    typedef int32_t  DWORD;
    typedef int16_t  int16;
     
    int16 TonerVolume = 3000;
     
    int main()
    {
        float direction          =  Step;
        float RunningSampleIndex = -TonerVolume;
     
        for(DWORD SampleIndex=0; SampleIndex <= Region1SampleCount; ++SampleIndex) {
    //      printf("% 4d: %6.2f\n", SampleIndex, RunningSampleIndex);
            printf("% 4d: %8.2f\n", SampleIndex, RunningSampleIndex);
     
            RunningSampleIndex += direction;
     
            if ((direction > 0) && (RunningSampleIndex > TonerVolume)) {
                RunningSampleIndex -=  (2 * Step);
                direction = -Step;
            } else if ((direction < 0) && (RunningSampleIndex < -TonerVolume)) {
                RunningSampleIndex += (2 * Step);
                direction = Step;
            }
        }
     
     
        return EXIT_SUCCESS;
    }
    Le gars préfère utiliser la courbe sinus pour faire varier trucmuche de -3000 à 3000, puis de 3000 à -3000 parce que la fonction inverse "automatiquement" le "sens"/ la "direction".
    le sinus travaille sur 1 plage [-1.0, 1.0], 1 simple multiplication fait l'affaire int16 SampleValue = (int16) (SineValue * TonerVolume);.

    C'est pour cela qu'il dit "lisse" ("smooth") parce que le signal carré -3000, 3000, -3000, 3000, ... du jour 8, lui n'est pas trop "lisse"

    Voila, comme ferait Barack Obama, "mic drop"

  18. #18
    Expert éminent sénior
    Avatar de Jipété
    Profil pro
    Inscrit en
    Juillet 2006
    Messages
    10 747
    Détails du profil
    Informations personnelles :
    Localisation : France, Hérault (Languedoc Roussillon)

    Informations forums :
    Inscription : Juillet 2006
    Messages : 10 747
    Points : 15 166
    Points
    15 166
    Par défaut
    Bonjour,

    Citation Envoyé par kaitlyn Voir le message
    J'ai regardé un peu ta vidéo, voici une autre ressource qui probablement t'intéressera
    https://www3.nd.edu/~dthain/courses/...ll2013/wavfile
    Tutafait !
    Grand merci à toi, je vais me régaler à jouer avec ça et l'outil proposé par foetus, ce compilateur en ligne (que je ne connaissais pas), ça c'est top !

    foetus que je remercie bien fort de se pencher sur ça et à qui je suggère une microscopique modification pour l'esthétique de la sortie :
    Citation Envoyé par foetus Voir le message
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
    //  printf("% 4d: %6.2f\n", SampleIndex, RunningSampleIndex);
        printf("% 4d: %8.2f\n", SampleIndex, RunningSampleIndex);
    8 au lieu de 6, ça change la vie !
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    avant :
     149: -1031.25
     150: -937.50
     151: -843.75
     152: -750.00
     153: -656.25
     154: -562.50
     155: -468.75
     156: -375.00
     157: -281.25
     158: -187.50
     159: -93.75
     160:   0.00
    après :
     149: -1031.25
     150:  -937.50
     151:  -843.75
     152:  -750.00
     153:  -656.25
     154:  -562.50
     155:  -468.75
     156:  -375.00
     157:  -281.25
     158:  -187.50
     159:   -93.75
     160:     0.00
    Bon week-end, je vous tiens au courant début de semaine prochaine...
    Il a à vivre sa vie comme ça et il est mûr sur ce mur se creusant la tête : peutêtre qu'il peut être sûr, etc.
    Oui, je milite pour l'orthographe et le respect du trait d'union à l'impératif.
    Après avoir posté, relisez-vous ! Et en cas d'erreur ou d'oubli, il existe un bouton « Modifier », à utiliser sans modération
    On a des lois pour protéger les remboursements aux faiseurs d’argent. On n’en a pas pour empêcher un être humain de mourir de misère.
    Mes 2 cts,
    --
    jp

  19. #19
    Membre éprouvé
    Femme Profil pro
    ..
    Inscrit en
    Décembre 2019
    Messages
    567
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Âge : 94
    Localisation : Autre

    Informations professionnelles :
    Activité : ..

    Informations forums :
    Inscription : Décembre 2019
    Messages : 567
    Points : 1 265
    Points
    1 265
    Par défaut
    Citation Envoyé par foetus Voir le message
    Édit : 92-93 vient de (SamplesPerSecond (48 000) / ToneHz (256)) / 2 ou SamplesPerSecond (48 000) / (2 * ToneHz (256)) = 93.75
    Mais dans la nouvelle version (avec le sinus), le gars n'utilise pas la variable HalfWavePeriod (qui divise par 2) parce que le 2 vient de la formule du sinus : A * sin(2 * pi * F * t + phase).
    Donc l'amplitude c'est TonerVolume (pourquoi ?) et la fréquence c'est SamplesPerSecond (48 000) / ToneHz (256) (pourquoi ?)
    Mais TonerVolume = 93.75 * 32 bizarre
    Il ne faut pas éditer ton message 10 heures plus tard parce que le forum ne l'indique pas et donc ça peut passer inaperçu.

    Sinon ta dernière ligne pour moi c'est une coïncidence.
    Ensuite SamplesPerSecond (48 000) / ToneHz (256), s'il fallait nommer cette opération ce serait SamplesPerPeriod et non la fréquence. Et si tu veux SamplesPerHalfPeriod, tu calcules SamplesPerPeriod / 2. L’intérêt de travailler sur l'une ou l'autre c'est pour forcer le passage à zéro (zero-crossing) au changement de signal, ça évite les artefacts. Comme cette notion fera tilte chez certains, dans un secteur d'activité tout aussi passionnant, je précise qu'ici le zéro est un zéro trigonométrique (donc PI est inclus) mais pas forcément scalaire.
    Enfin pourquoi Amplitude = ToneVolume, c'est un raccourci qui évidemment n'a pas lieu d’être, conf. mes messages précédents.

  20. #20
    Expert confirmé

    Homme Profil pro
    Directeur de projet
    Inscrit en
    Mai 2013
    Messages
    1 349
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Yvelines (Île de France)

    Informations professionnelles :
    Activité : Directeur de projet
    Secteur : Service public

    Informations forums :
    Inscription : Mai 2013
    Messages : 1 349
    Points : 4 191
    Points
    4 191
    Par défaut Lookup table ou calcul direct ?
    Bonjour,

    J'ai une interrogation sur le calcul en boucle de la sinusoïde. Certes ici il ne sert que pour un affichage de contrôle mais ce genre de calcul prépare généralement la création d'une table d'une période pour accélérer les calculs.

    Ce n'est pas nécessairement une bonne idée. Prenons les 500 Hz, il faut 44100/500 échantillons par période soit 88.2 échantillons. Le .2 oblige à avoir 5 périodes complètes pour éviter un saut de phase à la fin de chaque période (c'est à dire un spectre avec des rais et non une seule). L'alternative est d'avoir une interpolation mais cela impose des divisions et multiplications qui vont ruiner le gain en temps d'une table précalculée avec une pureté spectrale limitée.

    Même en temps réel, 44100 Hz représentent 22.6 us soit quelques dizaines de milliers d'opérations sur un processeur actuel. Je pense donc qu'un calcul direct est préférable.
    Cela pourrait se traduire par :
    • Une structure stocke l'angle alpha courant, le delta_alpha correspondant à la fréquence, et amp le coefficient d'amplitude.
    • Une fonction initialise la structure à partir d'un pointeur sur celle-ci (ce qui permet de multiplier les ondes) de la fréquence à générer et de l'amplitude.
    • Une autre fonction (de préférence inline) calcule la valeur actuelle et incrémente alpha de delta_alpha (éventuellement en retirant 2PI si dépassement - ce n'est important que pour la précision de l'angle si la fonction doit être appelée de très nombreuse fois).

    Bien sûr, avec un langage objet, encapsuler tout cela dans un objet, T_GenSin par exemple, aurait du sens.

    L'usage de double est effectivement recommandable d'autant que son format sur 64 bits est optimal pour les processeurs actuels. C'est pour la même raison que le format extended, avec ses 80 bits, n'est recommandé que pour des besoins de précision accrue.

    Salutations
    Ever tried. Ever failed. No matter. Try Again. Fail again. Fail better. (Samuel Beckett)

+ Répondre à la discussion
Cette discussion est résolue.
Page 1 sur 3 123 DernièreDernière

Discussions similaires

  1. [Lazarus] Lister les CharSets d'une font
    Par Jipété dans le forum Lazarus
    Réponses: 28
    Dernier message: 24/07/2023, 13h57
  2. [Python 3.X] Besoin d'un petit coup de main pour du Algo->Python
    Par Pierre_Euh dans le forum Général Python
    Réponses: 9
    Dernier message: 31/01/2019, 09h15
  3. Réponses: 1
    Dernier message: 12/03/2014, 22h58
  4. Réponses: 4
    Dernier message: 06/09/2013, 17h22
  5. UPDATE trop compliqué, besoin d'un petit coup de main ;)
    Par pwangen dans le forum Requêtes
    Réponses: 1
    Dernier message: 17/02/2006, 11h16

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo