Synchsafe Integers

Djembefola

Active Member
Licensed User
Longtime User
Messing around with id3v2 tags i got stuck on "synchsafe integers". :SHOCKED:

Synchsafe integers are integers that keep the highest bit zeroed, making seven bits out of eight available. Thus a 32 bit synchsafe integer can store 28 bits of information. 255 (00000000 11111111) encoded as a synchsafe integer is 383 (00000001 01111111).

Can someone help me convert "01111111 01111111 01111111 01111111" to "00001111 11111111 11111111 11111111" and vice versa?

i've found some c++ functions, which do the Synchsafe-To/From-Int Conversion, but c++ is chinese for me.

I've seen that there are Bitshifting Functions in B4A, but i don't know how to use them.
 

Djembefola

Active Member
Licensed User
Longtime User
B4X:
int synchsafe(int in)
{
        int out, mask = 0x7F;
 
        while (mask ^ 0x7FFFFFFF) {
                out = in & ~mask;
                out <<= 1;
                out |= in & mask;
                mask = ((mask + 1) << 8) - 1;
                in = out;
        }
 
        return out;
}
 
int unsynchsafe(int in)
{
        int out = 0, mask = 0x7F000000;
 
        while (mask) {
                out >>= 1;
                out |= in & mask;
                mask >>= 8;
        }
 
        return out;
}
 
Upvote 0

Djembefola

Active Member
Licensed User
Longtime User
50% solved

i guess, i have 50% of my problem solved by trial and error:

B4X:
Sub SynchSafeToInt(synchsafe As Int) As Int
  Dim a,b,c,d As Int
  a=Bit.And(synchsafe, 0x7f) 
  b=Bit.ShiftRight(Bit.And(synchsafe, 0x7f00),1)
  c=Bit.ShiftRight(Bit.And(synchsafe, 0x7f0000),2)
  d=Bit.ShiftRight(Bit.And(synchsafe, 0x7f000000),3)
  return Bit.Or(Bit.or(a,b), Bit.Or(c,d))
End Sub

At first sight this function does what it should do.

Hopefully one day i will understand my own coding :)
i have still no idea how to write the crresponding IntToSynchsafe Function.
:confused:
 
Upvote 0

Erel

B4X founder
Staff member
Licensed User
Longtime User
Try this:
B4X:
Sub Activity_Create(FirstTime As Boolean)
   Log(SynchSafe(255))
   Log(UnsynchSafe(383))
End Sub

Sub SynchSafe (In As Int) As Int
   Dim out, mask As Int
   mask = 0x7F
   Do While Bit.Xor(mask, 0x7FFFFFFF) <> 0
      out = Bit.And(in, Bit.Not(mask))
      out = Bit.ShiftLeft(out, 1)
      out = Bit.Or(out, Bit.And(in, mask))
      mask = Bit.ShiftLeft(mask + 1, 8) - 1
      in = out
   Loop
   Return out
End Sub
Sub UnsynchSafe (In As Int) As Int
   Dim out, mask As Int
   mask = 0x7F000000
   Do While mask <> 0
      out = Bit.ShiftRight(out, 1)
      out = Bit.Or(out, Bit.And(in, mask))
      mask = Bit.ShiftRight(mask, 8)
   Loop
   Return out
End Sub
 
Upvote 0
Top