Les Snippets

Connexion

entrelacement et désentrelacement de flux organisés en 16bits (ex: PCM 16bits)

Niveau requis pour utiliser/comprendre cette source : 1 ( Débutant )
Créé le 01/08/2006 11:07:38 et initié par _dune2_ [Liste]
Vue : 11985
Catégorie(s) : Multimédia, Algorithme
Langages dispo pour ce code :
- Assembleur x86
- C



Langage : Assembleur x86
Date ajout : 01/08/2006
Posté par _dune2_ [Liste]
.section .data
 
 .align 16;                            // on aligne les buffers sur 128bits (load/store SSE alignés)
 buffer_mono1:    .space 256*1024*2;    // buffer de 256K échantillons en 16bits signés mono(PCM classique)
 .align 16;                            // on aligne les buffers sur 128bits (load/store SSE alignés)
 buffer_mono2:    .space 256*1024*2;    // buffer de 256K échantillons en 16bits signés mono(PCM classique)
 .align 16;                            // on aligne les buffers sur 128bits (load/store SSE alignés)
 buffer_stereo:    .space 256*1024*2*2;  // buffer de 256K échantillons en 16bits signés stéréo entrelacé (PCM classique)
 
 nb_echantillons: .long 256*1024;      // nombre d'échantillons (attention: 1 échantillon = 2 octets !)
                                       // attention aussi a avoir un multiple de 8 echantillons !!
 
 .section .text
 
 ;// PARTIE ENTRELACEMENT
 entrelace:
      mov       $buffer_mono1,%eax;      // on charge le pointeur du 1er buffer mono dans EAX
      mov       $buffer_mono2,%ebx;      // on charge le pointeur du 2ème buffer mono dans EBX
      mov       $buffer_stereo,%edx;     // on charge le pointeur du buffer stéréo dans EDX
      mov       nb_echantillons,%ecx;    // on charge le contenu de nb_echantillons dans ECX
      sar       $3,%ecx;                 // on divise le nombre d'echantillons par 8
                                         // car on les traite 8 par 8
 boucle1:
      movdqa    (%eax),%xmm0;            // XMM0.W = [Md0 Md1 Md2 Md3 Md4 Md5 Md6 Md7] (Mono Droite) 
      movdqa    (%ebx),%xmm1;            // XMM1.W = [Mg0 Mg1 Mg2 Mg3 Mg4 Mg5 Mg6 Mg7] (Mono Gauche)
      pshufd    $0xE4,%xmm0,%xmm2;       // Recopie XMM0 dans XMM2 sans passer par l'unité de chargement SSE
      punpcklwd %xmm1,%xmm2;             // XMM2.W = [Md0 Mg0 Md1 Mg1 Md2 Mg2 Md3 Mg3]
      movdqa    %xmm2,(%edx);            // on écrit la première partie d'entrelacement
      punpckhwd %xmm1,%xmm0;             // XMM0.W = [Md4 Mg4 Md5 Mg5 Md6 Mg6 Md7 Mg7]
      movdqa    %xmm0,16(%edx);          // on écrit la deuxième partie d'entrelacement 16 octets plus loin
      add       $16,%eax;                // on se decale de 8 echantillons (16 octets) pour mono1
      add       $16,%ebx;                // on se decale de 8 echantillons (16 octets) pour mono2
      add       $32,%edx;                // on se decale de 8 echantillons (32 octets) pour stéréo
      dec       %ecx;                    // on decremente le nombre de paquet de 8 echantillons a traiter
      jnz       boucle1;                 // si ce n'est pas null, on continue a traiter
 fin_entrelace:                          // c'est fini ... on peut faire ce qu'on veut ensuite
 
 
 ;// PARTIE DESENTRELACEMENT
 desentrelace:
      mov       $buffer_mono1,%eax;      // on charge le pointeur du 1er buffer mono dans EAX
      mov       $buffer_mono2,%ebx;      // on charge le pointeur du 2ème buffer mono dans EBX
      mov       $buffer_stereo,%edx;     // on charge le pointeur du buffer stéréo dans EDX
      mov       nb_echantillons,%ecx;    // on charge le contenu de nb_echantillons dans ECX
      sar       $3,%ecx;                 // on divise le nombre d'echantillons par 8
                                         // car on les traite 8 par 8
 boucle2:
      movdqa    (%edx),%xmm0;            // XMM0.W = [Md0 Mg0 Md1 Mg1 Md2 Mg2 Md3 Mg3]
      movdqa    16(%edx),%xmm1;          // XMM1.W = [Md4 Mg4 Md5 Mg5 Md6 Mg6 Md7 Mg7]
      pshufd    $0xE4,%xmm0,%xmm2;       // Recopie XMM0 dans XMM2 sans passer par l'unite de chargement SSE
      pslld     $16,%xmm2;               // XMM2.W = [Mg0 0 Mg1 0 Mg2 0 Mg3 0]
      psrad     $16,%xmm2;               // XMM2.W = [0 Mg0 0 Mg1 0 Mg2 0 Mg3]
      movdqa    %xmm1,%xmm3;             // Recopie XMM1 dans XMM3
      pslld     $16,%xmm3;               // XMM3.W = [Mg4 0 Mg5 0 Mg6 0 Mg7 0]
      psrad     $16,%xmm3;               // XMM3.W = [0 Mg4 0 Mg5 0 Mg6 0 Mg7]
      packssdw  %xmm3,%xmm2;             // on packetise de double (32bits) vers word (16bits)
                                         // XMM2.W = [Mg0 Mg1 Mg2 Mg3 Mg4 Mg5 Mg6 Mg7]
      movdqa    %xmm2,(%eax);            // on stocke le resultat dans le 1er buffer mono
      psrad     $16,%xmm0;               // XMM0.W = [0 Md0 0 Md1 0 Md2 0 Md3]
      psrad     $16,%xmm1;               // XMM1.W = [0 Md4 0 Md5 0 Md6 0 Md7]
      packssdw  %xmm1,%xmm0;             // on packetise de double (32bits) vers word (16bits)
                                         // XMM0.W = [Md0 Md1 Md2 Md3 Md4 Md5 Md6 Md7]
      movdqa    %xmm0,(%ebx);            // on stocke le resultat dans le 2eme flux mono
      add       $16,%eax;                // on se deplace vers les 8 echantillons suivants (16 octets)
      add       $16,%ebx;                // on se deplace vers les 8 echantillons suivants (16 octets)
      add       $32,%edx;                // on se deplace vers les 8 echantillons suivants (32 octets)
      dec       %ecx;                    // on decremente le nombre de paquet de 8 echantillons a traiter
      jnz       boucle1;                 // si ce n'est pas null, on continue a traiter
 fin_desentrelace:                       // c'est fini ... on peut faire ce qu'on veut ensuite
 

Remarque :
Assembleur AT&T (à compiler avec gnu 'as' ou gcc) pour CPUs avec support SSE.
Langage : C
Date ajout : 01/08/2006
Posté par _dune2_ [Liste]
short mono1[256*1024];              // buffer mono 16bits
 short mono2[256*1024];              //  buffer mono 16bits
 short stereo[256*1024*2];            // buffer stéréo 16bits
 int nb_echantillons = 256*1024;  // nombre d'échantillons
 
 void entrelace()
 {
   short *_mono1 = mono1;
   short *_mono2 = mono2;
   short *_stereo  = stereo;
   int loop;
   for(loop=0;loop<nb_echantillons;loop++) {
     *_stereo++ = *_mono1++ ;
     *_stereo++ = *_mono2++ ;
   }
 }
 
 void desentrelace()
  {
    short *_mono1 = mono1;
    short *_mono2 = mono2;
    short *_stereo  = stereo;
    int loop;
    for(loop=0;loop<nb_echantillons;loop++) {
      *_mono1++ = *_stereo++ ;
      *_mono2++ = *_stereo++ ;
    }
  }
 


Snippets en rapport avec : Audio, Multiplexage, Flux



Codes sources en rapport avec : Audio, Multiplexage, Flux

{C / C++ / C++.NET} LECTEUR MULTIMEDIA AVEC GSTREAMER
Projet de programmation d'un lecteur multimédia en utilisant le formidable outil gstreamer. Ca fonct...

{Visual Basic, VB6, VB.NET, VB 2005} CLASS BASS
J'archive une de mes class vb6 que j'ai tenté de mettre à jour pour le .NET. Son utilisation semble ...

{Visual Basic, VB6, VB.NET, VB 2005} CLASS AUDIO (MCI WAV MMIO)
J'archive cette classe que je qualifie d'obsolète, elle peut toujours être utile c'est pour cela que...

{Visual Basic, VB6, VB.NET, VB 2005} LECTEUR DE NEWS RSS COMPLET
Bonjour, Lecteur de news RSS incluant un navigateur internet. Configuration compléte du programme...

{C# / C#.NET} FFMPEG.NET : WRAPPER .NET DE FFMPEG
Cette source est un wrapper .Net pour FFMPEG. Pour le moment, vous ne pouvez extraire ou convertir q...

{Javascript / DHTML} PETIT LECTEUR AUDIO HTML 5
Tout est dans le titre: Voici les bases d'un lecteur audio tirant profit de la balise audio du futu...

{JAVA / J2EE} CONVERSION D'UN FICHIER IMAGE CD AUDIO CIF CRÉÉ PAR EASY CD CREATOR, EN FICHIERS WAV.
Cet utilitaire Java en ligne de commande permet de convertir des fichiers images de CD Audio (extens...

{Javascript / DHTML} ANIMATION DU TEXTE
Ce script permet d'afficher un texte caractère par caractère en jouant un son. La méthode setInterva...

{Visual Basic, VB6, VB.NET, VB 2005} LECTEUR AUDIO EN VB
Voici un petit lecteur audio fait en VB (avec Visual Studio Pro 2010). Je ne sais pas si cela est im...

{Delphi} STREAM STRINGWRITER... UNE MICRO-LIBRAIRIE POUR ÉCRIRE DES CHAINES DANS UN FLUX
Cette micro-librairie (2 fonctions seulement) permet de lire et écrire des chaines de caractères dan...