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

- 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

Meilleure réponse
Messages postés
4304
Date d'inscription
samedi 16 octobre 2004
Dernière intervention
9 mars 2018
- 9 mai 2008 à 14:40
3
Merci
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

Merci f0xi 3

Avec quelques mots c'est encore mieux Ajouter un commentaire

Codes Sources a aidé 88 internautes ce mois-ci

Commenter la réponse de f0xi
Meilleure réponse
- 10 mai 2008 à 13:35
3
Merci
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

Merci Utilisateur anonyme 3

Avec quelques mots c'est encore mieux Ajouter un commentaire

Codes Sources a aidé 88 internautes ce mois-ci

Commenter la réponse de Utilisateur anonyme
Messages postés
4229
Date d'inscription
vendredi 23 juillet 2004
Dernière intervention
3 août 2018
- 7 mai 2008 à 12:48
0
Merci
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
- 7 mai 2008 à 13:13
0
Merci
Salut Cirec : j'ai vu cette source mais elle ne fait pas avancer rmon schmilblic .
Commenter la réponse de Utilisateur anonyme
Messages postés
7
Date d'inscription
mercredi 16 avril 2008
Dernière intervention
19 mai 2008
- 7 mai 2008 à 13:13
0
Merci
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
- 7 mai 2008 à 14:04
0
Merci
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
Messages postés
2684
Date d'inscription
jeudi 15 janvier 2004
Dernière intervention
26 juillet 2018
- 7 mai 2008 à 14:06
0
Merci
Salut,

Regarde les commentaires de ce source :




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

http://www.delphifr.com/livre-norme-midi-studio-musique-351.aspx
Commenter la réponse de Caribensila
- 7 mai 2008 à 14:50
0
Merci
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
- 7 mai 2008 à 14:51
0
Merci
Pardon 4 bits (une fonction éditer serait la bienvenue )
Commenter la réponse de Utilisateur anonyme
Messages postés
759
Date d'inscription
vendredi 21 mars 2003
Dernière intervention
1 octobre 2009
- 7 mai 2008 à 16:05
0
Merci
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
- 7 mai 2008 à 16:22
0
Merci
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
Messages postés
2684
Date d'inscription
jeudi 15 janvier 2004
Dernière intervention
26 juillet 2018
- 7 mai 2008 à 16:28
0
Merci
Delphi, c'est mieux que de compiler le C.
Commenter la réponse de Caribensila
Messages postés
759
Date d'inscription
vendredi 21 mars 2003
Dernière intervention
1 octobre 2009
- 7 mai 2008 à 16:33
0
Merci
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
Messages postés
759
Date d'inscription
vendredi 21 mars 2003
Dernière intervention
1 octobre 2009
- 7 mai 2008 à 16:38
0
Merci
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
Messages postés
4229
Date d'inscription
vendredi 23 juillet 2004
Dernière intervention
3 août 2018
- 7 mai 2008 à 21:06
0
Merci
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
- 7 mai 2008 à 21:10
0
Merci
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
Messages postés
4229
Date d'inscription
vendredi 23 juillet 2004
Dernière intervention
3 août 2018
- 7 mai 2008 à 22:57
0
Merci
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
Messages postés
4229
Date d'inscription
vendredi 23 juillet 2004
Dernière intervention
3 août 2018
- 7 mai 2008 à 23:09
0
Merci
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
- 8 mai 2008 à 04:56
0
Merci
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.