.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
Vous n'êtes pas encore membre ?
inscrivez-vous, c'est gratuit et ça prend moins d'une minute !
Les membres obtiennent plus de réponses que les utilisateurs anonymes.
Le fait d'être membre vous permet d'avoir un suivi détaillé de vos demandes et codes sources.
Le fait d'être membre vous permet d'avoir des options supplémentaires.