Pour jouer le son immédiatement et non pas à l'écriture du prochain '\n'?
L'alternative étant, bien sûr, de faire un fflush(stdout) après avoir écrit dessus. Mais utiliser stderr est plus court.
Version imprimable
Code:
1
2
3
4
5
6
7
8
9 printf("%c\n", 'BEL'); fflush(stdout); fprintf (stdout, "%c\n", '^G'); fflush(stdout); fputc(7, stdout) ; fflush(stdout); fprintf ( stdout, "\n%c\n", 7); fflush(stdout); printf ("%c\n", '\a');
Pas de son.Citation:
Another@DESKTOP-8007BEU ~
$ ./bip.exe
L
G
Quel est ton système? Ce prompt ne correspond pas au Windows 10 mentionné dans ta signature...
PS: Ça ne m'étonne pas que '^G' ne marche pas, n'ayant aucun souvenir d'avoir vu un quelconque support de ce type de séquence dans le standard C.
Window10, cygwin, x86_64-w64-mingw32-gcc-7.3.0.exe -Wall -ansi -std=c99 bip.c -o bip.exe
Ok, je ne connaissais pas cette subtilité. Je pensais que la bufferisation était identique sur tous les flux.
Mouais. fputc(car, stdout) me semble quand-même plus court, plus approprié, plus tout quoi :mrgreen:
Ceci dit, et sans plaisanter, ça ouvre tout de même un autre débat: vaut-il mieux écrire "plus court" mais faux (après-tout, stderr est fait pour faire transiter les messages d'erreurs et écrire dessus parce que c'est plus simple c'est quand-même pas tiptop) ou "moins court" mais plus correctement (en passant donc par le fameux fflush()) ???
A mon avis, je pense que la seconde option semble la meilleure à long terme...
Bah sur ce plan-là, à mon avis il vaut mieux faire pratique...
"stderr" n'est pas seulement utilisé pour "erreur", mais "erreur aussi dans le sens debug", ce qui veut dire mettre des traces et les observer au fur et à mesure...
Donc déjà ça allonge - pas mal - le code si tu fais sur un long programme partout des "stdout + fflush"..
D'autre part, en général quand on veut faire un "bip" c'est justement pour une alerte ou erreur... Il est donc parfaitement logique de se servir du stderr...
Enfin, il me semble que on peut s'activer à appliquer les justes utilisations sur des choses qui en valent la peine... La nuance entre stdout et stderr vient justement SEULEMENT de la bufferisation... Si tu fais un "stdout", sans le fflush, ça sort quand ca peut, des fois jamais si le programme se termine avant... :
Tu peux par exemple vouloir faire un stdout si tu veux faire sortir les lignes d'une matrice qui prend du temps à calculer, avec des "stderr" au milieu pour traces, et faire un fflush du stdout à la fin pour avoir toute la matrice....
Ca me semble plus utile et pratique de l'utiliser comme ça que d'arguer sur le fait que ça devrait être toujours utilisé pour des erreurs...
M'enfin, c'est mon "pansement", hein 8-)
@J4e8a16n :
Je ne sais pas si c'est le cas dans ton vrai code, mais dans celui que tu présentes, d'une part tu ne fais pas "toascii(7)" (en incluant "ctype.h" je crois), d'autre part le dernier ('\a') n'a pas de fflush.... Et enfin, comme je disais avant, essayer avec stderr pour la dernière instruction...
Je n'ai pas la dernière version de cygwin, mais sur mon ordi (HP, 64 bits, Windows XP), des "toascii(7)" marchaient il y a 5 ans... Evidemment depuis que j'ai Windows 10, j'ai pas testé.... ni re-compilé... ni ré-installé cygwin... :?
@J4e8a16n:
As-tu vérifié les "sons système" pour être sûr que tu as un son configuré pour ça? De mémoire, il me semble que c'est le "son par défaut" qui est joué par Windows quand on écrit un caractère BEL dans une console, mais tu peux aussi vérifier d'autres sons comme "astérisque".
...Et je conseillerais aussi d'essayer avec autre chose que Cygwin. Code::Blocks, par exemple.
Code:
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 #include <stdio.h> #include <stdlib.h> #include <unistd.h> /* sleep() */ #include <dos.h> /* #include <pc.h> #include <inlines/pc.h> #include <sys/cdefs.h> */ void outportb (unsigned short _port, unsigned char _data); /* <inlines/pc.h> */ unsigned char inportb (unsigned short _port); /* <inlines/pc.h> */ void onbeep(int freq) { int temp; long val = ((182 * 65535)/10)/freq; if (val > 65535) val = 65535; outportb(0x43,0xb6); outportb(0x42,val & 0xff); outportb(0x42,val >> 8); temp = inportb(0x61); temp |= 3; outportb(0x61,temp); } void offbeep(void) { int temp = inportb(0x61); temp &= 0xfc; outportb(0x61,temp); } int main(int argc, char *argv[]) { int a = atoi(argv[1]); if(a == 0) onbeep(65535); else onbeep(atoi(argv[1])); sleep(1000); offbeep(); printf("Usage: beep [frequency]\n"); return 0; }
Pourquoi ne la trouve-t-il pas? Elle est dans <inlines/pc.h>Code:
1
2
3
4
5
6
7
8
9
10
11 Another@DESKTOP-8007BEU ~/beep2 $ x86_64-w64-mingw32-gcc-7.3.0.exe -Wall -ansi -std=c99 beep2.c -o beep2.exe /tmp/ccx5zKjC.o:beep2.c:(.text+0x32)*: référence indéfinie vers «*outportb*» /tmp/ccx5zKjC.o:beep2.c:(.text+0x44)*: référence indéfinie vers «*outportb*» /tmp/ccx5zKjC.o:beep2.c:(.text+0x59)*: référence indéfinie vers «*outportb*» /tmp/ccx5zKjC.o:beep2.c:(.text+0x63)*: référence indéfinie vers «*inportb*» /tmp/ccx5zKjC.o:beep2.c:(.text+0x7f)*: référence indéfinie vers «*outportb*» /tmp/ccx5zKjC.o:beep2.c:(.text+0x98)*: référence indéfinie vers «*inportb*» /tmp/ccx5zKjC.o:beep2.c:(.text+0xb7)*: référence indéfinie vers «*outportb*» collect2: error: ld a retourné le statut de sortie 1
Quelle est la commande pour que gcc, ld or 'whatever' affiche tous les headers chargés?
Merci de me lire,
JPD
Bonjour,
En l'occurence, le lanceur du message est ld. Rappel de comment il s'inscrit dans le processus de compilation.
Et comment réglé : https://alexandre-laurent.developpez...theque/#LIII-B
On apprendra que ce n'est donc pas un problème d'include (de fichier d'en têtes).
Bonsoir,
Il est tout à fait possible de faire du son en informatique, c’est une question de formats. Avec un langage de programmation comment le C, il est possible de générer et stocker un signal sonore en une série d’octets dans le format audio de votre choix. MIDI, WAVE etc.. exemple en WAV source trouver sur le net et pour la compréhension du formats ici:
Code:
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 #include <stdio.h> #include <math.h> #include <stdlib.h> #define PI 3.14159265358979323846264338327 #define AMPLITUDE_MAXI 32767 unsigned int taux ; unsigned long int taille ; double *gauche, *droite ; double duree ; void ecrire_little_endian(unsigned int octets, int taille, FILE *fichier) { unsigned char faible ; while(taille > 0) { faible = octets & 0x000000FF ; fwrite(&faible, 1, 1, fichier) ; octets = octets >> 8 ; taille = taille - 1 ; } } void ecrire_en_tete_WAV(FILE *fichier) { unsigned short int nb_canaux = 2 ; unsigned short int nb_bits = 16 ; taux = 44100 ; duree = 60 ; taille = taux * duree ; unsigned long int nb_octets_donnees = (nb_bits / 8) * nb_canaux * taille ; gauche = calloc(taille, sizeof(double)) ; droite = calloc(taille, sizeof(double)) ; fwrite("RIFF", 4, 1, fichier) ; ecrire_little_endian(36 + nb_octets_donnees, 4, fichier) ; fwrite("WAVE", 4, 1, fichier) ; fwrite("fmt ", 4, 1, fichier) ; ecrire_little_endian(16, 4, fichier) ; ecrire_little_endian(1, 2, fichier) ; ecrire_little_endian(nb_canaux, 2, fichier) ; ecrire_little_endian(taux, 4, fichier) ; ecrire_little_endian(taux * nb_canaux * (nb_bits / 8), 4, fichier) ; ecrire_little_endian(nb_canaux * (nb_bits / 8), 2, fichier) ; ecrire_little_endian(nb_bits, 2, fichier) ; fwrite("data", 4, 1, fichier) ; ecrire_little_endian(taille * nb_canaux * (nb_bits / 8), 4, fichier) ; } void ecrire_donnees_normalisees_WAV(FILE *fichier) { unsigned int i ; double maxi = 1e-16 ; for (i = 0 ; i < taille ; i=i+1) { if (fabs(gauche[i]) > maxi) maxi = fabs(gauche[i]) ; if (fabs(droite[i]) > maxi) maxi = fabs(droite[i]) ; } for (i = 0 ; i < taille ; i=i+1) { ecrire_little_endian((int)(gauche[i]/maxi*AMPLITUDE_MAXI), 2, fichier) ; ecrire_little_endian((int)(droite[i]/maxi*AMPLITUDE_MAXI), 2, fichier) ; } } void mon_signal(double t1, double t2, double f, double Amp) { unsigned int i; double omega = 2 * PI * f ; double t = 0 ; double dt = 1.0 / taux ; double phi = 0 ; for (i=(unsigned int)(t1*taux) ; i<(unsigned int)(t2*taux) ; i=i+1) { gauche[i] = gauche[i] + Amp * sin(omega*t + phi) ; droite[i] = droite[i] + Amp * sin(omega*t + phi) ; t = t + dt ; } } int main(void) { FILE *fichier_wav = fopen("synthe.wav", "wb") ; ecrire_en_tete_WAV(fichier_wav) ; mon_signal(0.0, 5.0, 440.0, 1.0) ; ecrire_donnees_normalisees_WAV(fichier_wav) ; fclose(fichier_wav) ; free(gauche) ; free(droite) ; }
@Kanagi: Et comme vous l’avez souligné, le langage de programmation C est assez bas niveaux pour écrire les pilotes des cartes son permettant de jouer ou émettre un signal sonore.
@J4e8a16n:je ne sais pas ce que vous cherchez à faire, mais ce n’est évidemment pas la bonne façon de lire un fichier son et cela n’a rien à avoir à l’émission d’un son. La question est donc, savez-vous ce que vos faites au moins ...?
à bientôt.
Ce n'était pas nécessaire de me quote pour dire plus ou moins la même chose ,mais je vais pinailler le format MIDI ne permet pas de jouer un son il ne permet juste de jouer une partition ;)
(il indique néanmoins quel instrument on doit utiliser, mais ça demande d'avoir une petite banque de données de sample pour pouvoir le jouer).
Sinon le format WAV est très simple a lire , ça a du me prendre 5-10 min pour pouvoir l’utiliser.