Partage
  • Partager sur Facebook
  • Partager sur Twitter

CRÉEZ DES ONDES SONORES (Sinusoïdale) EN C

Besoin de votre aide

18 mars 2020 à 14:35:55

Bonjour,

Je suis étudiante en master d'électrotechnique, pour mon projet de semestre 2 qui traite de l’analyse de la qualité de l'énergie j'ai besoin d'un code écrit en c qui permet de générer en wav un signal sinusoïdale dans le quel je pourrais introduire des défauts (harmoniques).

Le code ci-après, Vu ce que l'auteur a mis dans  le for, décrit un signal carré périodique, qui, toutes les secondes, allonge sa période.

Période plus longue = son plus grave.

J'aimerais donc savoir comment le modifier pour avoir un signal sinusoïdale avec des défauts que j'aurais moi même choisi.

Dans l'attente de vos réponses.

Cordialement,

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <math.h>

#define FREQUENCE 44100
#define BITPERSAMPLE 16

typedef int int32;
typedef short int16;
typedef char int8;

struct WavHeader
{
	int8 FileTypeBlocID[4];
	int32 FileSize;
	int8 FileFormatID[4];
};

struct WavFmt
{
	int8 FormatBlocID[4];
	int32 BlocSize;
	int16 AudioFormat;
	int16 NbrCanaux;
	int32 Frequence;
	int32 BytePerSec;
	int16 BytePerBloc;
	int16 BitsPerSample;
};

FILE * wavfile_open( const char *filename )
{
	struct WavHeader head = {{'R','I','F','F'},0,{'W','A','V','E'}};
	struct WavFmt Fmt = {{'f','m','t',' '},16,1,1,FREQUENCE,FREQUENCE*BITPERSAMPLE/8,BITPERSAMPLE/8,BITPERSAMPLE};
	FILE* F;
	F = fopen(filename,"wb");
	if(!F)
		return 0;
	fwrite(&head,sizeof(head),1,F);
	fwrite(&Fmt,sizeof(Fmt),1,F);
	return F;
}

void wavfile_write(FILE *F, int16* data, int32 length )
{
	char subhead[5] = "data";
	fwrite(subhead,4,1,F);
	fwrite(&length,sizeof(length),1,F);
	fwrite(data,sizeof(short),length,F);
}

void wavfile_close( FILE *file )
{
	int file_length = ftell(file);
	int32 FileSize = file_length - 8;
	fseek(file,4,SEEK_SET);
	fwrite(&FileSize,sizeof(FileSize),1,file);
	fclose(file);
}



int main()
{
	FILE* F;
	int i;
	int nbsecondes = 10;
	int updown = 1;
	int16* datas = malloc(nbsecondes*FREQUENCE*sizeof(int16));

	for(i=0;i<nbsecondes*FREQUENCE;i++)
	{
		int largeurcarre = ((i/FREQUENCE)+1)*100;
		if (i%largeurcarre==0)
			updown= -1*updown;
		datas[i] = updown*16384;
	}

	F = wavfile_open("Sound.wav");
	if (!F)
		return -1;
	wavfile_write(F,datas,nbsecondes*FREQUENCE);
	free(datas);
	wavfile_close(F);
	return 0;
}

  • Partager sur Facebook
  • Partager sur Twitter
18 mars 2020 à 15:14:51

Bonjour,

Voici un sujet qui explique comment faire un signal sinus dans un .wav

https://openclassrooms.com/forum/sujet/le-format-wave-37889#.U30JKijDI_w

  • Partager sur Facebook
  • Partager sur Twitter
Architecture SDL                     Multithreading         
20 mars 2020 à 6:47:17

Bonjour,

J'ai pris connaissance du code proposé ( code ci-joint ) dans le liens que vous m'avez fourni, il génère bien un son sinusoïdal pur, mais mon soucis est que je ne sais pas comment y introduire des harmoniques (défauts) pour ne plus que le signal soit une sinusoïde. 

Pourriez  vous s'il vous plait m'expliquer comment faire.

Merci d'avance.

/*
 *  main.c
 *  Gestion des fichiers WAVE
 *
 *  Created by Pouet on 26/11/09.
 * 
 */
 
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <string.h>
#include <math.h>
 
/* Pour forcer l'alignement mémoire.
 * Normalement yen a pas besoin, mais au cas où ...
 * (merci Fvirtman  ) */
#pragma pack(push, 1)
 
/* Nombre de secondes pour notre fichier */
#define N_SEC 10
 
/* Formats audios
 * (je ne connais que le PCM ...) */
enum F_AUDIO {
    PCM = 1
};
 
/* Taille de l'en-tête subTaille1 */
enum T_AUDIO {
    T_PCM = 16
};
 
/* Canaux :
 *  Mono = 1 seule enceinte
 *  Stéréo = 2 enceintes
 *  GDC = 3 enceintes (gauche, droite, centre)
 *  GD_GD = 4 enceintes (avant gauche et droite, arrière gauche et droite)
 *  GDCS = 5 enceintes (GDC + Surround)
 *  All = 6 enceintes (GDC, centre gauche, centre droit, surround) */
enum CAN {
    MONO = 1,
    STEREO = 2,
    GDC = 3,
    GD_GD = 4,
    GDCS = 5,
    ALL = 6
};
 
/* Fréquence d'échantillonnage
 * Valeurs en hz*/
enum F_ECH {
    F_8K = 8000,
    F_11K = 11025,
    F_22K = 22050,
    F_41K = 44100,
    F_48K = 48000, /* Encodage d'un CD audio  */
    F_96K = 96000
};
 
/* Bits par échantillon */
enum BPE {
    BPE_8 = 8,
    BPE_16 = 16,
    BPE_24 = 24,
    BPE_32 = 32
};
 
#define T_ENTETE 44
 
/* L'en-tête fait 44 octets.
 * Il ne faut pas oublier d'enlever sizeof(void*) si
 * on utilise sizeof sur notre structure. */
struct wave {
    /* Le mot "RIFF" */
    char riff[4];
    /* La taille du fichier - 8
     * Ou subTaille2 + 44 - 8 */
    int32_t taille;
    /* Le mot "WAVE" */
    char wave[4];
     
    /* Le mot "fmt " */
    char fmt[4];
    /* Taille du header jusqu'à "data" */
    int32_t subTaille1;
    /* Format du fichier */
    int16_t formatAudio;
    /* Nombres de canaux */
    int16_t nombreCanaux;
    /* Fréquence d'échantillonnage */
    int32_t freqEch;
    /* ByteRate
     * Nombre d'ocets par seconde
     ** Calcul :
     *===> freqEch * nombreCanaux * bitsParEch / 8 */
    int32_t ByteRate;
    /* Alignement
     * Nombre d'octets par échantillon
     * Englobe tous les canaux !
     ** Calcul :
     *===> nombreCanaux * bitsParEch / 8 */
    int16_t align;
    /* Bits par échantillon */
    int16_t bitsParEch;
     
    /* Le mot "data" et la
     * taille des données */
    char Ndata[4];
    /* Taille des données */
    int32_t subTaille2;
     
    /* A allouer dynamiquement.
     * Contiendra les données */
    void *data;
};
 
void initWave(struct wave *wav) {
    /* Les constantes symboliques */
    strncpy(wav->riff, "RIFF", 4);
    strncpy(wav->wave, "WAVE", 4);
    strncpy(wav->fmt, "fmt ", 4);
    strncpy(wav->Ndata, "data", 4);
     
    //wav->taille = wav->subTaille2 = 0;
     
    wav->subTaille1 = T_PCM;
    wav->formatAudio = PCM;
    wav->nombreCanaux = STEREO;
    wav->freqEch = F_41K;
    wav->bitsParEch = BPE_16;
    wav->ByteRate = wav->freqEch * wav->nombreCanaux * (wav->bitsParEch / 8);
    wav->align = wav->nombreCanaux * (wav->bitsParEch / 8);
     
    /* On utilise la constante N_SEC pour créer notre fichier */
    /* On aura un fichier de N_SEC secondes */
    /* On peut calculer subTaille2 en fonction du byterate. Ce qui nous donne : */
    wav->subTaille2 = wav->ByteRate * N_SEC;
     
    /* On calcule la taille du fichier */
    wav->taille = wav->subTaille2 + 44 - 8;
     
    /* On alloue la partie données */
    wav->data = malloc(wav->subTaille2);
}
 
void genererPiste(struct wave *wav) {
    int16_t *data = wav->data;
    int cpt;
    double val;
     
    /* On crée une sinusoïde pour créer un jooooli son  */
    for (cpt = 0, val = 0.0; cpt < wav->subTaille2/2; cpt += 2, val += 0.0284951714612 /*0.0142475857306*/) {
        /* On met la même valeur pour les 2 enceintes */
        /* Essayez d'en mettre un à 0 et de laisser l'autre
         * Vous aurez un bruit que sur une seule enceinte  */
        data[cpt] = sin(val) * 32267;
        data[cpt+1] = sin(val) * 32267;
    }
}
 
int main(void) {
    struct wave wav = { 0 };
    FILE *fich = fopen("test.wav", "wb+");
     
    if (fich == NULL)
        return EXIT_FAILURE;
     
    /* Seul les paramètres taille, subTaille2 et data ne sont pas initialisés */
    initWave(&wav);
    /* On génère des données */
    genererPiste(&wav);
    /* On écris l'en-tête SANS LE wav->data */
    fwrite(&wav, T_ENTETE, 1, fich);
    /* On écris les data */
    fwrite(wav.data, wav.subTaille2, 1, fich);
     
    /* On libère notre mémoire, et on ferme le fichier */
    free(wav.data);
    fclose(fich);
    /* Voilà notre fichier son est créé  */
    return EXIT_SUCCESS;
}
  • Partager sur Facebook
  • Partager sur Twitter
20 mars 2020 à 13:17:15

Bonjour, Merci de retirer les lettres capitales de votre titre.

Majuscules abusives

L'écriture en majuscules est considérée comme une parole criée et diminue autant la lisibilité du texte que sa compréhension. Les majuscules abusives sont donc interdites aussi bien dans les titres que dans les messages.

Liens conseillés

  • Partager sur Facebook
  • Partager sur Twitter
20 mars 2020 à 14:14:12

Hello,

C'est au niveau de genererPiste() qu'il faut intervenir. Je n'ai pas essayé, mais je supose que le code suivant  génére des harmoniques

if(cpt%100<2) {
	data[cpt] = cos(val) * 32267;
	data[cpt+1] = cos(val) * 32267;
}
else {
	data[cpt] = sin(val) * 32267;
	data[cpt+1] = sin(val) * 32267;
}



-
Edité par edgarjacobs 20 mars 2020 à 14:14:49

  • Partager sur Facebook
  • Partager sur Twitter

On écrit "j'ai tort", pas "tord" qui est le verbe "tordre" à la 3ème personne de l'indicatif présent

20 mars 2020 à 15:16:44

Bonjour,

Il ne sert à rien de créer des sujets en doublons car ils vont être fermés !

Pour les harmoniques, il y a une réponse sur ce sujet :

https://openclassrooms.com/forum/sujet/introduire-des-harmoniques-dans-une-sinusoide

  • Partager sur Facebook
  • Partager sur Twitter
Architecture SDL                     Multithreading         
21 mars 2020 à 3:21:04

D'accord merci bien. J'ai bien reçu votre message



-
Edité par ZenaPico 21 mars 2020 à 16:22:46

  • Partager sur Facebook
  • Partager sur Twitter
26 mars 2020 à 23:30:39

Bonjour

SVP pourriez vous m'expliquer cette boucle, elle provient du code ci dessus, j'aimerais comprendre comment les points du signal sont générés sont stocker s'il vous plait.

for (cpt = 0, val = 0.0; cpt < wav->subTaille2/2; cpt += 2, val += 0.0284951714612 /*0.0142475857306*/) {
        /* On met la même valeur pour les 2 enceintes */
        /* Essayez d'en mettre un à 0 et de laisser l'autre
         * Vous aurez un bruit que sur une seule enceinte  */
        data[cpt] = sin(val) * 32267;
        data[cpt+1] = sin(val) * 32267;



Ci joint une capture d'écran d'une partie des échantillons en fonction du temps du signal précédent, que j'obtient grâce à un code qui génère un fichier .data d'un fichier Wav.

Saviez vous ce que signifie le -1.#INF00?

Merci d'avance.

-
Edité par ZenaPico 26 mars 2020 à 23:49:43

  • Partager sur Facebook
  • Partager sur Twitter
27 mars 2020 à 2:11:15

Bonjour, je ferme ce sujet pour non respect des règles du forum et non respect d'une demande de la modération.

Merci de lire les règles du forum AVANT de poster à nouveau.

Liens conseillés

  • Partager sur Facebook
  • Partager sur Twitter