Quality and Usage enhancement in TÉLÉSIA

Audio TEAP packetization, audio_mixage.h:

/**************************************************************************\
*          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 Caristan        Project 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

Audio TEAP packetization, audio_mixage.cc:

/**************************************************************************\
*          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 Caristan        Project 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