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

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Expert confirmé
    Avatar de Jipété
    Profil pro
    Inscrit en
    Juillet 2006
    Messages
    11 154
    Détails du profil
    Informations personnelles :
    Localisation : France, Hérault (Languedoc Roussillon)

    Informations forums :
    Inscription : Juillet 2006
    Messages : 11 154
    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,

  2. #2
    Expert confirmé
    Homme Profil pro
    Ingénieur développement matériel électronique
    Inscrit en
    Décembre 2015
    Messages
    1 600
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 62
    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 600
    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 confirmé
    Avatar de Jipété
    Profil pro
    Inscrit en
    Juillet 2006
    Messages
    11 154
    Détails du profil
    Informations personnelles :
    Localisation : France, Hérault (Languedoc Roussillon)

    Informations forums :
    Inscription : Juillet 2006
    Messages : 11 154
    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.

  4. #4
    Expert confirmé
    Homme Profil pro
    Ingénieur développement matériel électronique
    Inscrit en
    Décembre 2015
    Messages
    1 600
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 62
    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 600
    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 confirmé
    Avatar de Jipété
    Profil pro
    Inscrit en
    Juillet 2006
    Messages
    11 154
    Détails du profil
    Informations personnelles :
    Localisation : France, Hérault (Languedoc Roussillon)

    Informations forums :
    Inscription : Juillet 2006
    Messages : 11 154
    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.

  6. #6
    Expert confirmé
    Homme Profil pro
    Analyste/ Programmeur
    Inscrit en
    Juillet 2013
    Messages
    4 776
    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 776
    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
    Membre prolifique
    Avatar de Sve@r
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Février 2006
    Messages
    12 851
    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 851
    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
    Membre très actif
    Avatar de sambia39
    Homme Profil pro
    No Comment
    Inscrit en
    Mai 2010
    Messages
    551
    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 : 551
    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

  9. #9
    Expert confirmé
    Avatar de Jipété
    Profil pro
    Inscrit en
    Juillet 2006
    Messages
    11 154
    Détails du profil
    Informations personnelles :
    Localisation : France, Hérault (Languedoc Roussillon)

    Informations forums :
    Inscription : Juillet 2006
    Messages : 11 154
    Par défaut
    Bonsoir,

    j'ai lu cette histoire de LUT, ma foi, pourquoi pas, mais elle sortira d'où, cette table ?

    Sinon, j'ai continué à me prendre la tête avec des choses maraboutées, je vous montre :

    en partant d'un exemple très léger venant de là avec 3 fichiers, j'ai tout condensé en un seul et les seules modifs que j'apporte concernent la variable Bits_Per_Sample, qu'on rencontre habituellement à 16 mais qui peut prendre la valeur 8, 24, 32 ou 64.

    Alors si le code fonctionne au poil avec 16, ça part en vrac complet avec 8 et je n'arrive pas à trouver où, c'est pourquoi je vous appelle à mon secours : voilà les images (réduites) en 16 bits puis en 8 :
    Nom : sinus16M.png
Affichages : 219
Taille : 22,0 Ko

    Nom : sinus8M.png
Affichages : 228
Taille : 28,0 Ko

    et voilà les données remontées par le logiciel qui affiche ces jolies images (16M = 16bitsMono, 8M = 8bitsMono) :
    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
                                File : 16M.wav, 176 444 bytes
                        SubChunkSize : 16
                        Audio format : $0001 (1 = PCM, uncompressed)
                            Channels : 1
              SampleRate (samples/s) : 44100
                 Byte rate (bytes/s) : 88200
                         Block align : 2
                     Bits per sample : 16
          Size of data block (bytes) : 176400
             Total number of samples : 88200
       Number of samples per channel : 88200
                        Duration (s) : 2.0
     
                                File : 8M.wav, 176 444 bytes
                        SubChunkSize : 16
                        Audio format : $0001 (1 = PCM, uncompressed)
                            Channels : 1
              SampleRate (samples/s) : 44100
                 Byte rate (bytes/s) : 44100
                         Block align : 1
                     Bits per sample : 8
          Size of data block (bytes) : 176400
             Total number of samples : 176400
       Number of samples per channel : 176400
                        Duration (s) : 4.0
    Pourquoi la durée est-elle multipliée par 2, tout comme le Total number of samples ?
    Merci pour les retours,

    Le code du prog :
    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
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    /*
    A simple sound library for CSE 20211 by Douglas Thain (dthain@nd.edu).
    This work is made available under the Creative Commons Attribution license.
    https://creativecommons.org/licenses/by/4.0/
     
    For course assignments, you should not change this file.
    For complete documentation, see:
    http://www.nd.edu/~dthain/courses/cse20211/fall2013/wavfile
    */
     
     
    #include <stdio.h>
    #include <math.h>
    #include <stdlib.h>
    #include <time.h>
    #include <string.h>
    #include <errno.h>
    #include <inttypes.h>
     
    #define SAMPLES_PER_SECOND 44100
     
    const int NUM_SAMPLES = (SAMPLES_PER_SECOND * 2);
     
    struct wavfile_header {
    	char	riff_tag[4];
    	int	riff_length;
    	char	wave_tag[4];
    	char	fmt_tag[4];
    	int	fmt_length;
    	short	audio_format;
    	short	num_channels;
    	int	sample_rate;
    	int	byte_rate;
    	short	block_align;
    	short	bits_per_sample;
    	char	data_tag[4];
    	int	data_length;
    };
     
    FILE * wavfile_open( const char *filename )
    {
    	struct wavfile_header header;
     
    	int samples_per_second = SAMPLES_PER_SECOND;
    //	int bits_per_sample = 16;
    	int bits_per_sample = 8;
     
    	strncpy(header.riff_tag,"RIFF",4);
    	strncpy(header.wave_tag,"WAVE",4);
    	strncpy(header.fmt_tag,"fmt ",4);
    	strncpy(header.data_tag,"data",4);
     
    	header.riff_length = 0;
    	header.fmt_length = 16;
    	header.audio_format = 1;
    	header.num_channels = 1;
    	header.sample_rate = samples_per_second;
    	header.byte_rate = samples_per_second*(bits_per_sample/8);
    	header.block_align = bits_per_sample/8;
    	header.bits_per_sample = bits_per_sample;
    	header.data_length = 0;
     
    	FILE * file = fopen(filename,"wb+");
    	if(!file) return 0;
     
    	fwrite(&header,sizeof(header),1,file);
    	fflush(file);
    	return file;
    }
     
    void wavfile_write( FILE *file, short data[], int length )
    {
    	fwrite(data,sizeof(short),length,file);
    }
     
    void wavfile_close( FILE *file )
    {
    	int file_length = ftell(file);
     
    	int data_length = file_length - sizeof(struct wavfile_header);
    	fseek(file,sizeof(struct wavfile_header) - sizeof(int),SEEK_SET);
    	fwrite(&data_length,sizeof(data_length),1,file);
     
    	int riff_length = file_length - 8;
    	fseek(file,4,SEEK_SET);
    	fwrite(&riff_length,sizeof(riff_length),1,file);
     
    	fclose(file);
    }
     
    int main()
    {
    	short waveform[NUM_SAMPLES];
    	double frequency = 440.0;
    	int volume = 32000;
    	int length = NUM_SAMPLES;
     
    	int i;
    	for(i=0;i<length;i++) {
    		double t = (double) i / SAMPLES_PER_SECOND;
    //pour 16bits	waveform[i] = volume*sin(frequency*t*2*M_PI);
    		waveform[i] = 127 + (volume*sin(frequency*t*2*M_PI));
    	}
     
    	FILE * f = wavfile_open("essai_onefile.wav");
    	if(!f) {
    		printf("couldn't open essai_onefile.wav for writing: %s",strerror(errno));
    		return 1;
    	}
     
    	wavfile_write(f,waveform,length);
    	wavfile_close(f);
     
    	return 0;
    }

  10. #10
    Membre Expert
    Femme Profil pro
    ..
    Inscrit en
    Décembre 2019
    Messages
    698
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Âge : 95
    Localisation : Autre

    Informations professionnelles :
    Activité : ..

    Informations forums :
    Inscription : Décembre 2019
    Messages : 698
    Par défaut
    J'ai juste survolé ton code, dès la ligne 93 «rien ne va plus».
    En 8bits, le type ne devrait pas être un short mais quelque chose comme un signed (unsigned) char. D'où deux fichiers de même taille.
    Et deux lignes plus loin, l'amplitude. Elle ne doit pas excéder 127 ou 255. D'où (avec ce qui précède) ton effet électroencéphalogramme.
    Il faut que tu regardes ta doc, il y a un problème de signature sur le format 8bits mais je ne sais plus de quel ordre.

  11. #11
    Expert confirmé
    Homme Profil pro
    Analyste/ Programmeur
    Inscrit en
    Juillet 2013
    Messages
    4 776
    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 776
    Par défaut
    Le compileur t'aide en te disant l'erreur et te dit quoi choisir (j'ai juste affiché tes valeurs)

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    main.cpp: In function ‘int main()’:
    main.cpp:26:12: warning: format ‘%d’ expects argument of type ‘int’, but argument 2 has type ‘double[-Wformat=]
       26 |   printf("%d\n", (127.0 + (volume * sin(frequency * t * 2 * M_PI))));
          |           ~^     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
          |            |            |
          |            int          double
          |           %f
    Effectivement, sin te retourne 1 double, et donc toi tu le mets dans 1 tableau de short


    Citation Envoyé par Guesset Voir le message
    quand on regarde la vidéo (j'ai juste échantillonné la vidéo sans respecter Nyquist et Shannon ) on voit des techniques d'optimisation (genre v <<=1; v <<=1; v <<=1; v <<=1; v <<=1;...) qui n'ont plus lieu d'être aujourd'hui.
    D'ailleurs il y a 1 note sur la page internet "Bitshifting to divide will give you unexpected results for negative numbers. Use actual divide instead."
    Effectivement sur les nombres négatifs cela marche moins bien : soit le signe saute/ gêne (il faut sûrement le "masquer") soit avec 1 complément à 1/ complément à 2 cela doit donner des valeurs "inattendues"

  12. #12
    Expert confirmé
    Avatar de Jipété
    Profil pro
    Inscrit en
    Juillet 2006
    Messages
    11 154
    Détails du profil
    Informations personnelles :
    Localisation : France, Hérault (Languedoc Roussillon)

    Informations forums :
    Inscription : Juillet 2006
    Messages : 11 154
    Par défaut
    Salut bonjour,

    merci pour ce code mais je n'arrive pas à retomber sur tes valeurs ou sur ton dessin...

    J'ai utilisé un TImage de 512x512 et dans ton code il y a ça :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
      imax  := 255;
      delta := 2.0*PI/imax;                         // On fait "presque" un tour complet
      volume:= 0.0;
      img.Canvas.Brush.Color:= 0;
      img.Canvas.FillRect(0,0,256,512);
    et moi, pour avoir le même dessin que toi, je suis obligé de modifier en
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    //imax  := 255;
      imax  := 511;
    ...
    //img.Canvas.FillRect(0,0,256,512); // pourquoi 256 ?
    // de toute façon, résultat identique avec 512 dessous
      img.Canvas.FillRect(0,0,512,512);
    Mais alors, les valeurs sont fausses : de haut en bas,
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    127.0 (ok)
    512
    255
    257
    Est-ce que c'est parce que je suis sous Linux Debian 64 bits ?

    Autre chose : le rendu des couleurs...
    Nom : 3zooms.png
Affichages : 159
Taille : 25,4 Ko

    à gauche le bord gauche de ton image bien zoomée et par-dessus une loupe observant la même zone sur mon image, on voit bien qu'il y a un problème de fidélité des couleurs.
    Mêmes remarques au centre et au bord droit (où j'ai mis la loupe en haut pour éviter d'avoir une image trop large) : une idée ?


    Seconde question (déjà posée) : Maintenant, à quoi ça sert, ce bel outil ?

+ Répondre à la discussion
Cette discussion est résolue.

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