/*
 __  __  _____  ____  __  __  __   
(  \/  )(  _  )(  _ \(  )(  )(  )  
 )    (  )(_)(  )(_) ))(__)(  )(__ 
(_/\/\_)(_____)(____/(______)(____)


AUTEURS	    : Aymeric & Samira
DATE        : 10/06/2003
FICHIER     : modul.cpp
DESCRIPTION : module un message en frequence
	      donnees reportees dans signal.dat

*/


#include <iostream.h>
#include <fstream.h>
#include <math.h>
#include <stdlib.h>

/* ---------------------------------------------- */
/* ------ declaration des parametres connus ----- */
/* ---------------------------------------------- */

// taille maximale d'un message
#define LONGUEUR 254
// rapidite de modulation (en bauds)
const int rapidite=75;
// frequence d'echantillonnage (en Hz)
const int Fe=16000;
// frequence de modulation d'un bit 0 (en Hz)
const float f0=390;
// frequence de modulation d'un bit 1 (en Hz)
const float f1=450;
// amplitude (en V)
const float amplitude=20;
// fanion de debut de trame = 10101011
const int code_depart[8]={1,1,0,1,0,1,0,1};


/* ---------------------------------------------- */
/* ---------- declaration des fonctions --------- */
/* ---------------------------------------------- */

float sinus(float,float,float,float);
void asc2bin(int,int[]);


/* ---------------------------------------------- */
/* --------- fonction main du programme --------- */
/* ---------------------------------------------- */

int main(void)
{
	char message[LONGUEUR];
	int signal[8];

	cout << "\nRentrez le message :" << endl;
	//cin >> message;
	cin.getline(message,LONGUEUR);

	int taille=strlen(message);
	
	int indice=0;
	// on ajoute 2 octets a la taille du message
	// 1 octet representant un delimiteur indiquant le debut du message
	// +1 octet indiquant la taille du message en octets
	// taille_tab est la taille dynamique du tableau
	// taille est en octet donc on le multiplie par 8 pour avoir le nombre de bits auquel
	// on multiplie le nombre de points par bit (Fe/rapidite+1)
	int taille_tab=(taille+2)*8*(Fe/rapidite+1);
	
	short * tab;
	tab=new short[taille_tab];
	bool debut=true;
	bool long_msg=true;

	// pour chaque caractere composant le message
	for (int l=0; l < taille; l++)
	{
		// on traite normalement le message en convertissant chaque caractere en 8 bits
		if (!debut && !long_msg) asc2bin(message[l],signal);
		
		float t=0.0;
		float frequence;

		// si debut==true alors on envoi le delimiteur de debut
		if (debut)
		{
			for (int x=0; x < 8; x++)
				signal[x]=code_depart[x];
			l--;
		}

		// si long_msg==true et debut==false on envoit la taille du message
		if (long_msg && !debut)
		{
			asc2bin(taille,signal);
			l--;
		}
		
		// pour chaque bit composant le caractere a transmettre
		for (int i=0; i < 8; i++)
		{
			// selon qu'on a un 0 ou un 1 on prend une frequence differente
			if (signal[i] == 0) frequence=f0;
			else frequence=f1;

			// pour chaque point
			for (int j=0; j < (Fe/rapidite+1); j++)
			{
				// un point tous les 1/Fe secondes
				t+=1.0/(float)Fe;
				tab[indice++]=sinus(frequence,0,amplitude,t);
			}
		}

		if (long_msg && !debut)	long_msg=false;

		if (debut) debut=false;

	}
	
	// ouverture du flux vers le fichier en ecriture afin d'y inscrire les donnees
	fstream f("signal.dat",ios::out);

	// on se place au debut du fichier
	f.seekp(ios::beg);

	// on copie tout notre tableau dans le fichier
	for (int k=0; k < indice; k++)
	{
		f << tab[k] << endl;
	}

	f.close();
	
	cout << endl << indice << " points calcules" << endl;
		
	delete []tab;
	
	return(0);
	
}


/* ---------------------------------------------- */
/* -------------- fonctions utiles -------------- */
/* ---------------------------------------------- */

// execute la fonction sinus selon divers parametres
float sinus(float frequence, float phase, float a, float t)
{
	return(a*sinf(2*M_PI*frequence*t + phase));
}

// transforme le code ascii du caractere en un nombre binaire de 8 bits
void asc2bin(int caractere, int resultat[])
{
	for (int i=0; i < 8; i++)
	{
		resultat[i]=caractere%2;
		caractere=caractere/2;
	}
}


