/**************************************************************************\ * Copyright (c) 1991,1992,1993,1994,1995 INRIA siege, FRANCE. * * Copyright (c) 1993, 1994, 1995, Pierre leonard * * * * Permission to use, copy, modify, and distribute this software and * * its documentation for any purpose and without fee is hereby granted, * * provided that this copyright notice and this permission notice appear * * in all copies, and that both that copyright notice and this permission * * notice appear in supporting documentation. * * WE MAKE NO REPRESENTATIONS ABOUT THE ACCURACY OR SUITABILITY OF THIS * * MATERIAL FOR ANY PURPOSE. IT IS PROVIDED "AS IS", WITHOUT ANY EXPRESS * * OR IMPLIED WARRANTIES. * * * * This software and its documentation has been produced by the TELESIA * * project. The TELESIA project focuse these research on the Teleworking * * on Wide Area Network, the usage through a wide experimentation plan. * * * * The TELESIA Team is currently composed by: * * * * - Alain CaristanProject manager * * - Pierre De La Motte * * - Andrzej Wozniak * * - Pierre Leonard * * * * Many thank's to : * * * * - Christian Donot MBONE Manager * * - Olivier Marset * * - Georges Gyory * * - Philippe Riguet * * * * The TELESIA project is sponsored by: * * * * - INRIA siege (Rocquencourt) * * - ARISTOTE, an association of important users, studying, testing * * and promoting advanced technologie in the network field, * * interoperability, multimedia. * * - Pierre Leonard, from October 1993 until January 1995 * * * * The TELESIA patners are: * * * * - PAGEIN, a European project dedicated to the sharing of high * * computing ressources, * * - Rodeo, INRIA Sophia Antipolis network project. * * * * * * This file was created by: Pierre Leonard * * creation date: Novembre 1994 * * * * This file receive contributions from: * * * \**************************************************************************/ // // // Gestion d'un systeme de mise en paquet et de mixage // d'un flux audio sur reseau IP // /* * Auteur : P. Leonard * Date : Novembre 1994 * * fonctionnalites : * mise en paquet UDP, d'un flux audio * prise en compte de la nature volatile des protocols UDP * exploitation des methodes de mise en paquet * pour offrir un premier niveau de brouyage du son. * * Copyright Novembre 1994 (c) Pierre Leonard, Inria Rocquencourt */ #ifndef HAUDIO_MIXAGE #define HAUDIO_MIXAGE #include #include #include #include "general_types.h" #include "protocol_rtp.h" #include "audio_def.h" // AUDIO_HEADER = 64 // spreading functions extern u_char paq[8]; extern u_char ech[8]; extern u_char invpaq[8]; extern u_char invech[8]; extern int errno; const int AUDIO_HEADER = 64 ; // place reserved before the sample // copy d'un echantillon de son de 16 octets // sample copy. size fixed to 16 bytes // Copyright (C) Novembre 1994, Pierre Leonard, INRIA Rocquencourt inline void copyech (char* from, char* to) { #ifdef REORD_DEBUG fprintf(stderr,"copyech from %lx to %lx\n",(long) from,(long) to); #endif ((int*) to)[0] = ((int*) from)[0]; ((int*) to)[1] = ((int*) from)[1]; ((int*) to)[2] = ((int*) from)[2]; ((int*) to)[3] = ((int*) from)[3]; }; // computing of the spreading functions // Copyright (C) Novembre 1994, Pierre Leonard, INRIA Rocquencourt inline int indshuffle (int idpaq, int idech) { return (paq[idech]*128+ech[idpaq]*16); }; // computing of the inverted spreading functions // Copyright (C) Novembre 1994, Pierre Leonard, INRIA Rocquencourt inline int indinvshuffle (int idpaq, int idech) { int retour; retour = invech[idech]*128+invpaq[idpaq]*16; #ifdef REORD_DEBUG fprintf(stderr,"indinvshuffle %d : %d\n",invpaq[idpaq],retour); #endif return (retour); }; const int MIXAGE_VOIES_VIDE = -1; class reordonne: public elemd { private: u_int identite; // identite de la voie (adresse IP) // channel identity, with the IP address short nbpret; // nombre de paquets prets a sortir // nb sound samples ready to be played u_short mseqcour; // sequence courante // actual sequence number u_short seqprec; // sequence precedente // previous sequence number short ison; // indice de l'echantillon de son // sound sample index u_char flagpaq[8]; // paquets / echantillons recus // flag for each network packet received rtpbuf* precedent; // paquet precedent pour les trous // previous network packet, holes management rtpbuf* enattente; // entree / sortie en attendant le code // sound sample ready to be played rtpbuf* son[2]; // echantillon de son en remplissage // sound sample being received u_char silence[128]; // silence // sound silence void shufflepaquet (u_char* from, char* to, int ipaq); void shuffleflush (u_short sequence); void doubletrou (u_short debut, u_short fin); public: reordonne(); ~reordonne(); void create (u_int nom); // creation d'une voie audio // create an audio channel void rentre ( rtpbuf* paquet); // paquet a traiter // take that network packet rtpbuf* sortir(); // donne moi un paquet // give me a sound sample inline int pret(){ // y il a t'il un paquet de pret a lire return (nbpret != 0); // is there any sound sample to play }; inline u_int getidentite() { // rend l'identite de la voie de son return(identite); // give me the channel identity }; }; // methode de gestion du mixage de flux audio // etape 1 differentiation des flux sur l'adresse d 'emission // etape 2 remise en ordre des echantillons de son // etape 3 mixage des voies de son sans synchronisation // etape 4 synchronisation entre les voies et l'exterieur // audio channel mixing : // 1) sort the channel with there identity (ip address) // 2) re-ordering the sound samples // 3) sound mixing // 4) synchronization of the audio and the other media severs // Copyright (C) Novembre 1994, Pierre Leonard, INRIA Rocquencourt class mixage { private: reordonne* voies; // voies son a reordonner / channel queue short nbvoies; // nombre de voies audio / nb channels short nbpret; // nombre d'echantillons prets a sortir // nb sound samples ready to go out // rtpbuf* echantillon; // echantillon de son pret a sortir public: mixage(); ~mixage(); // formatting of the output packets with the spreading functions // Copyright Novembre 1994 (c) Pierre Leonard, Inria Rocquencourt void send (u_char* ppbuf, u_char* outbuf, proto_rtp & rtpip) { int ipaq, iech; for (ipaq = 0; ipaq < 8; ipaq= ipaq +1) for (iech = 0; iech < 8; iech=iech+1) copyech ((char*)&ppbuf[ipaq*128+iech*16], (char*)&outbuf[AUDIO_HEADER + indshuffle(ipaq,iech)]); for (ipaq = 0; ipaq < 8; ipaq=ipaq+1) { if (rtpip.send ((char*)&outbuf[AUDIO_HEADER+ipaq*128], 128) < 0) { perror("audio_mixage::send,error when sending datagram packet"); }; }; }; void rentre ( rtpbuf* paquet); // paquet a traiter // network packet to process rtpbuf* sortir(); // donne moi un echantillon de son // give me a sound sample inline int pret() // il y a t'il un echantillon pret a sortir { return (nbpret); // is there a sound sample to play }; }; #endif
/**************************************************************************\ * Copyright (c) 1991,1992,1993,1994,1995 INRIA siege, FRANCE. * * Copyright (c) 1993, 1994, 1995, Pierre leonard * * * * Permission to use, copy, modify, and distribute this software and * * its documentation for any purpose and without fee is hereby granted, * * provided that this copyright notice and this permission notice appear * * in all copies, and that both that copyright notice and this permission * * notice appear in supporting documentation. * * WE MAKE NO REPRESENTATIONS ABOUT THE ACCURACY OR SUITABILITY OF THIS * * MATERIAL FOR ANY PURPOSE. IT IS PROVIDED "AS IS", WITHOUT ANY EXPRESS * * OR IMPLIED WARRANTIES. * * * * This software and its documentation has been produced by the TELESIA * * project. The TELESIA project focuse these research on the Teleworking * * on Wide Area Network, the usage through a wide experimentation plan. * * * * The TELESIA Team is currently composed by: * * * * - Alain CaristanProject manager * * - Pierre De La Motte * * - Andrzej Wozniak * * - Pierre Leonard * * * * Many thank's to : * * * * - Christian Donot MBONE Manager * * - Olivier Marset * * - Georges Gyory * * - Philippe Riguet * * * * The TELESIA project is sponsored by: * * * * - INRIA siege (Rocquencourt) * * - ARISTOTE, an association of important users, studying, testing * * and promoting advanced technologie in the network field, * * interoperability, multimedia. * * - Pierre Leonard, from October 1993 until January 1995 * * * * The TELESIA patners are: * * * * - PAGEIN, a European project dedicated to the sharing of high * * computing ressources, * * - Rodeo, INRIA Sophia Antipolis network project. * * * * * * This file was created by: Pierre Leonard * * creation date: Novembre 1994 * * * * This file receive contributions from: * * * \**************************************************************************/ // // // Gestion d'un systeme de mise en paquet et de mixage // d'un fluc audio sur reseau IP // /* * Auteur : P. Leonard * Date : Novembre 1994 * * fonctionnalites : * new audio packetization. * mise en paquet UDP, d'un flux audio * prise en compte de la nature volatile des protocols UDP * exploitation des methodes de mise en paquet * pour offrir un premier niveau de brouyage du son. * * Copyright Novembre 1994 (c) Pierre Leonard, Inria Rocquencourt */ #define NO_MIX_DEBUG 1 #define NO_REORD_DEBUG 1 #include "audio_mixage.h" extern proto_rtp rtpip; u_char paq[8] = {7,4,1,6,3,0,5,2}; u_char invpaq[8] = {5,2,7,4,1,6,3,0}; u_char ech[8] = {0,1,2,3,4,5,6,7}; u_char invech[8] = {0,1,2,3,4,5,6,7}; // methode de gestion du mixage de flux audio // etape 1 differentiation des flux sur l'adresse d 'emission // etape 2 remise en ordre des echantillons de son // etape 3 mixage des voies de son sans synchronisation // etape 4 synchronisation entre les voies et l'exterieur // audio channel mixing : // 1) sort the channel with there identity (ip address) // 2) re-ordering the sound samples // 3) sound mixing // 4) synchronization of the audio and the other media severs // creation de la methode de mixage des voies audio // create the mixing audio channel class // Copyright (C) 1994, 1995, Pierre Leonard, INRIA Rocquencourt. mixage::mixage () { voies = (reordonne*) new(reordonne); nbvoies = 0; nbpret = 0; }; // Copyright (C) 1994, 1995, Pierre Leonard, INRIA Rocquencourt. mixage::~mixage() { reordonne* cour; if (voies != 0) { do { cour = (reordonne*) voies->avance(); #ifdef MIX_DEBUG fprintf(stderr,"MIXAGE::detruireliste courrant : %x\n",cour); #endif cour->dechaine(); delete (cour); } while (voies == voies->avance()); } }; // decoder le paquet reseau, en fonction de sa voie audio // decode the network packet, depending of it's audio channel // Copyright (C) 1994, 1995, Pierre Leonard, INRIA Rocquencourt. void mixage::rentre ( rtpbuf* paquet) // paquet a traiter { reordonne* voiecour; #ifdef MIX_DEBUG fprintf(stderr,">> mixage::rentre\n"); #endif // rentrer le paquet dans sa file voiecour = voies; do { if (voiecour->getidentite() == paquet->getfromaddr()) { goto filetrouvee; }; } while (voies != (voiecour = (reordonne*) voiecour->avance())); if (nbvoies != 0) { voiecour = new (reordonne); voies->chainedevant(voiecour); }; voiecour->create (paquet->getfromaddr()); filetrouvee: voiecour->rentre(paquet); #ifdef MIX_DEBUG fprintf(stderr,"<< mixage::rentre\n"); #endif return; // rechercher un echantillon a jouer dans une file // find a sound sample to play // ici on mixera le son / mixe the sound here }; // sortir un echantillon de son d'une des files, // ou l'echantillon unique apres mixage // get out a sound sample from a queue or after the global mixing // Copyright (C) 1994, 1995, Pierre Leonard, INRIA Rocquencourt. rtpbuf* mixage::sortir() // donne moi un echantillon de son // give me a sound sample { reordonne* voiecour; rtpbuf* retour; #ifdef MIX_DEBUG fprintf(stderr,">> mixage::sortir\n"); #endif // rechercher un echantillon a jouer dans une file voiecour = voies; // looking for a sound sample do { if (voiecour->pret()) { retour = voiecour->sortir(); goto paquettrouve; }; } while (voies != (voiecour = (reordonne*) voiecour->avance())); #ifdef MIX_DEBUG fprintf(stderr,"<< mixage::sortir VIDE\n"); #endif return ((rtpbuf*)MIXAGE_VOIES_VIDE); // ne devrait pas arriver // never go here paquettrouve: nbpret = nbpret - 1; voies = (reordonne*)voies->avance(); // change de premier pour supp. prio // found : new first sound sample #ifdef MIX_DEBUG fprintf(stderr,"<< mixage::sortir avec paquet %lx\n",(long) retour); #endif return (retour); }; // distribue les echantillons de son dans le nouveau paquet // en fonction des lois de repartition. // re-ordering the cell and sample of sound depending of the // two functions, and the packet sequence number // Copyright (C) 1994, 1995, Pierre Leonard, INRIA Rocquencourt. inline void reordonne::shufflepaquet (u_char* from, char* to, int ipaq) { int iech; #ifdef REORD_DEBUG fprintf(stderr,"shufflepaquet from %lx to %lx ipaq %x -> ",(long) from, (long) to, ipaq); #endif for (iech = 0; iech<8; iech= iech +1) copyech ((char*) &(from[iech*16]), (char*) &(to[indinvshuffle(ipaq,iech)])); flagpaq[ipaq] = 1; }; // creation tableau des flags a 0. echantillon de silence // clear the arrived packet flag table, create the silence packet // Copyright (C) 1994, 1995, Pierre Leonard, INRIA Rocquencourt. reordonne::reordonne () { int i; nbpret = 0; mseqcour = 0xffff; precedent = 0; ison = 0; for (i = 0; i < 8; i=i+1) flagpaq[i] = 0; for (i = 0; i < 128; i=i+1) silence[i] = 0xff; }; // Copyright (C) 1994, 1995, Pierre Leonard, INRIA Rocquencourt. reordonne::~reordonne() { free (son[0]); free (son[1]); }; // creation d'une voie audio // create an audio channel // Copyright (C) 1994, 1995, Pierre Leonard, INRIA Rocquencourt. void reordonne::create (u_int nom) { identite = nom; son[0] = creerrtpbuf(); son[1] = creerrtpbuf(); #ifdef REORD_DEBUG fprintf(stderr,"reordonne::create %lx %lx\n",(long) son[0], (long) son[1]); #endif seqprec = 0xffff; }; // flush les paquets en preparation // end of sequence. Flush the re-ordered sample. Holes are filled with silence // Copyright (C) 1994, 1995, Pierre Leonard, INRIA Rocquencourt. void reordonne::shuffleflush(u_short mseqpaq) { char* pcons; int i; #ifdef REORD_DEBUG fprintf(stderr,"shuffleflush : "); #endif son[ison]->getdata((char**) &pcons); for (i = 0; i < 8; i=i+1) { // le paquet est il bien recu if (flagpaq[i] != 1) { // sinon remplissage silence #ifdef REORD_DEBUG // there are holes, fill them fprintf(stderr,"silence de %x ",i); #endif shufflepaquet (silence, pcons, i); }; flagpaq[i] = 0; // reinit des drapeaux / clear the flag table }; // for nbpret = nbpret +1; enattente = son[ison]; // ajouter l'heure / time stamp here ison = (ison+1) & 0x01; #ifdef REORD_DEBUG fprintf(stderr,"new ison %d\n",ison); #endif if (mseqpaq == 0xffff) { // BOS recu / Begin of sync. received seqprec = 0xffff; mseqcour = 0xffff; } else { mseqcour = mseqpaq; }; }; // remplissage du trou avec le paquet precedent // fill the holes with the preceding cells // Copyright (C) 1994, 1995, Pierre Leonard, INRIA Rocquencourt. void reordonne::doubletrou (u_short seqprec, u_short seqpaq) { char* pcons; char* ppaq; int i; if (seqprec != (seqpaq -1)) { #ifdef REORD_DEBUG fprintf(stderr,"un trou ds paquet %x prec %x adr %lx\n", seqpaq,seqprec,(long) precedent); #endif precedent->getdata((char**) &ppaq); son[ison]->getdata((char**) &pcons); for (i = ((seqprec) & 7) ; i < ((seqpaq-1) & 7); i=i+1) { #ifdef REORD_DEBUG fprintf(stderr,"doublage %x\n",i); #endif shufflepaquet ((unsigned char*) ppaq, pcons, i); }; }; }; // paquet a traiter // take that network packet and process it // Copyright (C) 1994, 1995, Pierre Leonard, INRIA Rocquencourt. void reordonne::rentre ( rtpbuf* paquet) { int ipaq, lr; u_short mseqpaq; // macro sequence du paquet // macro sequence number of the packet u_short seqpaq; // sequence du paquet // sequence number of the packet char* ppaq; // donnees du paquet a traiter // data to process for that packet char* pcons; // donnees resultantes // resulting datas #ifdef REORD_DEBUG fprintf(stderr,">> reordonne::rentre\n"); #endif if (paquet->getoption(&pcons) == RTP_BOS) { shuffleflush(0xffff); return; }; seqpaq = paquet->getseq(); mseqpaq = (paquet->getseq() -1) & 0x0fff8; // sequence continue // still in the sequence #ifdef REORD_DEBUG fprintf(stderr," seqprec %x seqpaq %x mseqpaq %x mseqcour %x addr %lx\n", seqprec,seqpaq, mseqpaq,mseqcour,(long) paquet); #endif if (mseqpaq != mseqcour) { if (mseqcour == 0xffff) { son[ison]->clone(paquet); mseqcour = mseqpaq; if (precedent != 0) doubletrou (seqprec, seqpaq); } else { if (precedent != 0) doubletrou (seqprec, seqpaq); shuffleflush(mseqpaq); son[ison]->clone(paquet); #ifdef REORD_DEBUG fprintf(stderr,"reordonne::rentre paquet pret\n"); #endif }; // else mseqcour == 0xffff }; // if mseqpaq != mseqcour ipaq = (paquet->getseq() -1) & 0x07; // indice de paquet -> ech... // compute the packet index lr = paquet->getdata((char**) &ppaq); #ifdef REORD_DEBUG fprintf(stderr,"reordonne::rentre ipaq %x taille donnees %d\n",ipaq,lr); #endif lr = son[ison]->getdata((char**) &pcons); shufflepaquet ((unsigned char*) ppaq, (char*) pcons, ipaq); if (precedent != 0) { doubletrou (seqprec, seqpaq); rtpip.libere(precedent); }; precedent = paquet; seqprec = seqpaq; #ifdef REORD_DEBUG fprintf(stderr,"<< reordonne::rentre\n"); #endif }; // donne moi un echantillon // give me a sample // Copyright (C) 1994, 1995, Pierre Leonard, INRIA Rocquencourt. rtpbuf* reordonne::sortir() { #ifdef REORD_DEBUG fprintf(stderr,">> reordonne::sortir\n"); #endif nbpret = nbpret -1; #ifdef REORD_DEBUG fprintf(stderr,"<< reordonne::sortir\n"); #endif return(enattente); };
Copyright (C) 1994, 1995, Pierre Léonard, TÉLÉSIA, INRIA Rocquencourt