// Exemple de constitution d'un fichier son au format wav
#include<iostream>
#include<fstream>
#include<cmath>
#include<stdlib.h>
using namespace std;
int main()
{
  int 
    duto=2, // durée totale du fichier son en seconde
    ff=44100, // nombre de points d'échantillonnage par seconde = fréquence d'échantillonnage
    dyn=16, // nombre de bits consacrés au codage de chaque point d'échantillonnage de chaque canal = dynamique 
    nc=2,  // nombre de canaux (stéréo : 2)
    amp=pow(2,dyn-1)-1, // amplitude max de chaque point d'échantillonnage
    ntp=duto*ff; // nombre total de points d'échantillonnage par canal dans le fichier son
  double tmp,dpi=2*M_PI,f1=220,f2=f1,cam=5e-5; // f1 et f2 fréquences des signaux sinusoïdaux échantillonnés et cam coefficient d'amortissement des notes dans cet exemple
  int i,n,dun=ff/2; short sval; // dun durée de chaque note dans cet exemple
  //-----------------------------------------------------------------------------------------------------
  // Ouverture du fichier son (apparemment pas de différence entre les deux lignes suivantes) :
  //fstream lulu("son_wav.wav",ios::out|ios::binary);
  fstream lulu("son_wav.wav",ios::out);
  //-----------------------------------------------------------------------------------------------------
  // Écriture de l'en tête du fichier son :
  lulu.write("RIFF",4); // chaîne de caractères "RIFF"
  n=44+ntp*dyn/8*nc-8; lulu.write((char*)&n,4); // taille totale du fichier son en octets moins 8 octets
  lulu.write("WAVE",4); // chaîne de caractères "WAVE"
  lulu.write("fmt ",4); // chaîne de caractères "fmt "
  n=16; lulu.write((char*)&n,4); // nombre d'octets du bloc "fmt " moins 8 octets
  n=1; lulu.write((char*)&n,2);  // format du stockage dans le fichier (1: PCM, ...)
  n=nc; lulu.write((char*)&n,2); // nombre de canaux
  n=ff; lulu.write((char*)&n,4); // fréquence d'échantillonnage
  n=dyn/8*nc*ff; lulu.write((char*)&n,4); // nombre d'octets à lire par seconde
  n=dyn/8*nc; lulu.write((char*)&n,2); // nombre d'octets à lire par point d'échantillonnage pour la totalité des canaux
  n=dyn; lulu.write((char*)&n,2); // nombre de bits consacrés au codage de chaque point d'échantillonnage de chaque canal
  lulu.write("data",4); // chaîne de caractères "data"
  n=ntp*dyn/8*nc; lulu.write((char*)&n,4); // taille totale en octets des valeurs échantillonnées sur les différents canaux  
  //-----------------------------------------------------------------------------------------------------
  // Écriture des valeurs échantillonnées sur les différents canaux
  cout << sizeof(int) << " " << sizeof(long) << " " << sizeof(short) << endl;
  for(i=0;i<ntp;i++)
    {
      tmp=sin(i*dpi*f1/ff)*exp(-cam*(i%dun)); // voie 1, tmp doit appartenir à [-1,1]
      sval=tmp*amp;
      lulu.write((char*)&sval,dyn/8);
      tmp=sin(i*dpi*f2/ff)*exp(-cam*(i%dun)); // voie 2, tmp doit appartenir à [-1,1]
      sval=tmp*amp;
      lulu.write((char*)&sval,dyn/8);
    }
  lulu.close();
  //-----------------------------------------------------------------------------------------------------
  system("mplayer son_wav.wav");
  system("audacity son_wav.wav");
  return 0;
}
#if 0
-----------------------------------------------------------------------------
Le fichier son son_wav.wav peut être édité avec emacs dans lequel on passe en mode hexa par Esc-x hexl-mode
-----------------------------------------------------------------------------
Références :
http://fr.wikipedia.org/wiki/WAVEform_audio_format
http://ccrma.stanford.edu/courses/422/projects/WaveFormat/
http://technology.niagarac.on.ca/courses/ctec1631/WavFileFormat.html
-----------------------------------------------------------------------------
#endif
