Stratégie pour décaler des bits [Résolu]

Utilisateur anonyme - 7 mai 2008 à 11:48 - Dernière réponse :  Utilisateur anonyme
- 10 mai 2008 à 13:35
Salut la compagnie ,

Je travaille sur les fichiers midi : les évènements midi utilisent un paramètre qui est un DeltaTime et qui peut (et doit ) codé sur 32 bi</gras>. Sauf qu'il y a un sauf  (ben oui sinon c'est pas drole).

Z'explique le truc :

Prenons un longword bidon :

10000001   10110001   10110001   1010001

Selon la norme Midi il faut sucré pour chaque Bytes le premier bit (ou le dernier si on va de la gauche vers la droite)

On obtient donc ceci

(1)0000001   (1)0110001   (1)0110001   (1)010001

On rafistole le tout (Encore un truc à la Mac Gyver ) :

On obtient  0000001 0110001  0110001 010001

On remplace les bits "perdus" par des zéros

On obtient : 0000 0000001 0110001  0110001 010001

Même si je connais les opérateurs binaires, je n'ai aucune idée de comment faire la chose.

Merci à vous
Afficher la suite 

Votre réponse

29 réponses

f0xi 4304 Messages postés samedi 16 octobre 2004Date d'inscription 9 mars 2018 Dernière intervention - 9 mai 2008 à 14:40
+3
Utile
masquage du 7 eme bit :

byte : $7F (1000-0000)
word: $7F7F (1000-0000-1000-0000)
longword : $7F7F7F7F
int64 : $7F7F7F7F7F7F7F7F

pouf

masque bit 0
$E

masque bit 1
$D

masque bit 2
$B

masque bit 3
$7

et comme les bits se repete en hexa par mot de 4 bits ...

masque bit 4
$EF

masque bit 5
$DF (SDF lol)

masque bit 6
$BF

masque bit 7
$7F

etc...

et on repetre pour du 16, 32, 64 bits.

ensuite pour tout ce qui est decalage/rotation :

assembleur : SHL, SHR, ROL, ROR
+ pour manipuler les octets : XCHG, BSWAP

Cette réponse vous a-t-elle aidé ?  
Commenter la réponse de f0xi
Utilisateur anonyme - 10 mai 2008 à 13:35
+3
Utile
Salut,

Je tiens à tous vous remercier pour votre aider. Merci aux personnes qui m'ont aidé en privé (Twinuts, Sheorogath, Philippe).

Voila la procédure pour écrite la variable Length Quantitie :

Procedure WriteVLQ(Value:Word;MS:TMemoryStream);
Var
  Buffer, Count, Index:Word;
Begin
  Buffer:=Value AND $7F;
  Value:=Value SHR 7;
  Count:=0;
  While Value>0 Do
    Begin
      Buffer:=Buffer SHL 8;
      Buffer:=Buffer OR $80;
      Buffer:=Buffer+ (Value AND $7F);
      Value:=Value SHR 7;
      Inc(Count);
    End;
  For Index:=Count DownTo 0 Do
    Begin
      MS.Write(Buffer,1);
      Buffer:=Buffer SHR 8;
    End;
End;

Désolé d'avoir été un peu lourd mais sans ce fichu delta time, je ne pouvais plus avancer
Cette réponse vous a-t-elle aidé ?  
Commenter la réponse de Utilisateur anonyme
Cirec 4221 Messages postés vendredi 23 juillet 2004Date d'inscription 11 mai 2018 Dernière intervention - 7 mai 2008 à 12:48
0
Utile
Salut,

regarde cette source elle t'aidera à comprendre ^^

http://www.delphifr.com/codes/APPLICATION-OPERATEUR-LOGIQUE-SUR-DEUX-BYTES-REPRESENTATION-BINAIRE_32397.aspx

 
@+
Cirec

<hr siz="" />
Commenter la réponse de Cirec
Utilisateur anonyme - 7 mai 2008 à 13:13
0
Utile
Salut Cirec : j'ai vu cette source mais elle ne fait pas avancer rmon schmilblic .
Commenter la réponse de Utilisateur anonyme
Tavounet 7 Messages postés mercredi 16 avril 2008Date d'inscription 19 mai 2008 Dernière intervention - 7 mai 2008 à 13:13
0
Utile
J'ai été voir le lien sur ta réponse cirec et là, il me semble que le problème est bien plus complexe, il ne s'agit pas d'une vulgaire opération. ^^

Francky, est-ce que tu peux récupérer tes bits un par un?
Si oui, j'ai peut-être une idée.

Tu pars d'un longword 00000000 00000000 00000000 00000000.

Tu récupères le premier bit puis tu décales ton longword à droite en insérant le bit récupéré.

Idem pour le deuxième, troisième...

Tu as juste à "sauter" les 1 que tu veux virer.

Une fois tes 28 bits récupérés, tu fais un décalage à droite avec insertion de 0 quatre fois, et tu obtiendras ta valeur normalement.

Je ne sais pas si ça fonctionne, mais à tester ^^

Bon courage 
Commenter la réponse de Tavounet
Utilisateur anonyme - 7 mai 2008 à 14:04
0
Utile
Salut

En fait je ne récupère pas les messages midi : c'est pour faire un fichier midi.
Un lien pourles explications .

Si l'utilisateur veut ajouter une note : la procédure suivante est lancée :
procedure TMidiWriter.Add_NoteOn_Event(Const DeltaTime : LongWord; Const Channel, KeyNumber, Velocity: byte);
Et là il faut transformer le Delta Time en virant les premiers bits.

Pour être honnète j'ai trouvé ceci :

void WriteVarLen (register long value)
{
register long buffer;
buffer = value & 0x7f;
while ((value >>= 7) > 0)
{
buffer <<= 8;
buffer |= 0x80;
buffer += (value & 0x7f);
}
while (TRUE)
{
putc(buffer & 0xFF,outfile);
if (buffer & 0x80)
buffer >>= 8;
else
break;
}
}

doubleword ReadVarLen ()
{
register doubleword value;
register byte c;
if ((value = getc(infile)) & 0x80)
{
value &= 0x7f;
do
{ value (value <<7) + ((c getc(infile)) & 0x7f);
} while (c & 0x80);
}
return (value);
}

Manque de bol c'est du C donc j'y comprend que dalle et cette saloperie d'opérateur <<= je l'ai trouvé nul part donc je sais pas ce que c'est.

Merci A++
.
Commenter la réponse de Utilisateur anonyme
Caribensila 2674 Messages postés jeudi 15 janvier 2004Date d'inscription 11 mai 2018 Dernière intervention - 7 mai 2008 à 14:06
0
Utile
Salut,

Regarde les commentaires de ce source :




http://www.delphifr.com/codes/CONVERTISSEUR-BINAIRE_40942.aspx
Commenter la réponse de Caribensila
Caribensila 2674 Messages postés jeudi 15 janvier 2004Date d'inscription 11 mai 2018 Dernière intervention - 7 mai 2008 à 14:18
0
Utile
... Et ce livre devrait te passionner  :)))

http://www.delphifr.com/livre-norme-midi-studio-musique-351.aspx
Commenter la réponse de Caribensila
Utilisateur anonyme - 7 mai 2008 à 14:50
0
Utile
Salut Cari : la fonction de f0xi AllToBinStr(const Buffer; const bSize : integer; var OutBinStr : string); pourrait éventuellement me dépanner. Mais je trouve ca lourd tout ca pour déplacer 4 octets . Ca fait pas propre à mon gout (Je sais je suis chiant mais apres c'est qui qui va se faire gronder quand il va poster le source???? C'est francky ).

Je vais voir du coté de l'Assembleur (En même temps mon pc est plus sous garantis donc j'hésite : l'asm peut etre dangereux  sous les mains de Francky )
Commenter la réponse de Utilisateur anonyme
Utilisateur anonyme - 7 mai 2008 à 14:51
0
Utile
Pardon 4 bits (une fonction éditer serait la bienvenue )
Commenter la réponse de Utilisateur anonyme
cs_Kenavo 759 Messages postés vendredi 21 mars 2003Date d'inscription 1 octobre 2009 Dernière intervention - 7 mai 2008 à 16:05
0
Utile
Elle est où la contrepèterie dans le titre ??




procedure Virons4Bits (var v: longword);
begin
  v := v and $7F7F7F7F;
  v : = (v+ v and $7F) div 2;      // 2^7 - 1
  v := (v + v and $3FFF) div 2;   // 2^14 - 1
  v : = (v + v and $1FFFFF) div 2; // 2^21 - 1


end;






C'est pour décaler les sons ??

Ken@vo








Code, Code, Codec !
Commenter la réponse de cs_Kenavo
Utilisateur anonyme - 7 mai 2008 à 16:22
0
Utile
Non Kenavo c'est pour formater le paramètre Delta Time des midis . Ta procédure supprime des bits mais pas les bons  : je vais regarder cela ce soir
Commenter la réponse de Utilisateur anonyme
Caribensila 2674 Messages postés jeudi 15 janvier 2004Date d'inscription 11 mai 2018 Dernière intervention - 7 mai 2008 à 16:28
0
Utile
Delphi, c'est mieux que de compiler le C.
Commenter la réponse de Caribensila
cs_Kenavo 759 Messages postés vendredi 21 mars 2003Date d'inscription 1 octobre 2009 Dernière intervention - 7 mai 2008 à 16:33
0
Utile
Ou alors :

procedure Virons4BitsEncore(var v : longword);
type
  TTabByte = array [0..3] of byte;
var
  TByte : TTabbyte absolute v; // TByte et v partagent les mêmes octets
begin
  v: = Tbyte[0] and $7f + (Tbyte[1] and $7f)*$80 + (Tbyte[2] and $7f)*$4000 + (Tbyte[3] and $7f)*$200000;
end;

Ken@vo







Code, Code, Codec !
Commenter la réponse de cs_Kenavo
cs_Kenavo 759 Messages postés vendredi 21 mars 2003Date d'inscription 1 octobre 2009 Dernière intervention - 7 mai 2008 à 16:38
0
Utile
Vérifie Francky !
(et ne me dit pas que le dernier octet du longword est est réellement un septet comme dans ton exemple)

Ken@vo








Code, Code, Codec !
Commenter la réponse de cs_Kenavo
Cirec 4221 Messages postés vendredi 23 juillet 2004Date d'inscription 11 mai 2018 Dernière intervention - 7 mai 2008 à 21:06
0
Utile
Alors mon lien n'était pas bon ... hein ^^

et il a utilisé quoi Kenavo alors
me semble bien que ce sont des opérateurs logiques

 
@+
Cirec

<hr siz="" />
Commenter la réponse de Cirec
Utilisateur anonyme - 7 mai 2008 à 21:10
0
Utile
Ah ben celle la elle est bonne : un message vide.

J'ai fais un test : 11111111 11111111 11111111 11111111 devient
11111111 11111111 11111111 00001111.

Désoé Kénavo mais c'est pas bon ;).

@Cirec : mais j'ai pas dis qu'il ne fallait pas utiliser les opérateurs logiques mais le probleme c'est que c'est truc là j'y arrive jamais
Commenter la réponse de Utilisateur anonyme
Cirec 4221 Messages postés vendredi 23 juillet 2004Date d'inscription 11 mai 2018 Dernière intervention - 7 mai 2008 à 22:57
0
Utile
tiens bizzare j'obtiens pas la même chose que toi ???? :




Départ :=  11111111 11111111 11111111 11111111


Arivée :=   1111111 1111111 1111111 1111111





 






@+
Cirec





<hr siz="" />
Commenter la réponse de Cirec
Cirec 4221 Messages postés vendredi 23 juillet 2004Date d'inscription 11 mai 2018 Dernière intervention - 7 mai 2008 à 23:09
0
Utile
et en corrigant l'erreur de ton exemple (si c'est réellement une erreur) de Septet en Octet
ça le fait très bien ^^
10000001 10110001 10110001 10110001 Devient

1 0110001 0110001 0110001

Alors Septet ou Octet ?

 
@+
Cirec

<hr siz="" />
Commenter la réponse de Cirec
Utilisateur anonyme - 8 mai 2008 à 04:56
0
Utile
Salut,

"10000001 10110001 10110001 10110001  Devient

1  0110001  0110001  0110001"

Vous avez pas compris En fait il faut supprimer les premiers bits de chaque octet, coller ce qui reste. Et mettre à gauche 4 zéros pour tomber sur 32 bits.

"Since 81 is larger than 80, you can see that the 00 byte is also
part of the VLV. Lets look at 81 00 in binary notation:
10000001 00000000


Separate the continuation bit from the data bits:
1 0000001 0 0000000


Now you can see in binary notation what you can also see in hex notation --
that the first byte expects at least one more byte to follow it in the VLV.
Remove the continuation bits:
0000001 0000000


This is the actual number that is represented by the VLV value <tt>81 00</tt>,
but maybe we should convert to decimal or hex so you understand it better.
First, combine all of the bits into one clump:
00000010000000


I will convert first to hexadecimal, and later to decimal. For hexadecimal
conversion of a binary number, arrange the digits into groups of 4, starting
with the least siginificant (smallest, right) side of the number:
00 0000 1000 0000


There are two zeros left on the left size, so add two more zeros to make a
grouping of four digits:
0000 0000 1000 0000


We can do this in decimal notation to show why this can be done:
the number 0045 and 45 are the same number.
Now, convert the binary groupings into hexadecimal digits:
0000 0000 1000 0000"
0 0 8 0

Donc si on prend ton exemple Cirec :

<strike>1</strike>0000001 <strike>1</strike>0110001 <strike>1</strike>0110001 <strike>1</strike>0110001

On obtient  0000001   0110001   0110001   0110001

Il reste 0000001   0110001   0110001   0110001
On rajoute 4 zéros 0000 0000001   0110001   0110001   0110001

On obtient donc 00000000  00101100 01011000 10110001 et non  
10110001 0110001 0110001
Commenter la réponse de Utilisateur anonyme

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.

Stratégie pour décaler des bits - page 2