Sure.

First, to be more specific, what I'd like is to convert a 80 bit 
extended precision float stored in a 10 byte string to and from a ruby 
Float. In fact it's okay if I can convert it to and from a ruby Integer 
as I don't need any decimals. Sample rate of AIFF sound file is stored 
as an 80 bit extended precision float. I don't know why because mostly 
this is an integer value and I'd be happy with an Integer.

I've tried to convert the read_ieee_extended and write_ieee_extended 
methods of the following java class:
http://www.docjar.com/html/api/com/sun/media/sound/AiffFileReader.java.html

I've changed float input and output to integer.

Method read_ieee_extended seem to work fine. I've tried it with two 
different AIF files.

def read_ieee_extended(str)
  arr = str.unpack("n5")

  exponent = arr[0]
  hi_mantissa = arr[1] << 16 | arr[2]
  lo_mantissa = arr[3] << 16 | arr[4]

  if exponent == 0 and hi_mantissa == 0 and lo_mantissa == 0
    0
  else
    if exponent == 0x7FFF
      3.40282346638528860e+38
    else
      exponent -= 16383
      exponent -= 31
      f = hi_mantissa * (2**exponent)
      exponent -= 32
      f += lo_mantissa * (2**exponent)
      f
    end
  end.to_i
end

Method write_ieee_extended has errors:

def write_ieee_extended(i)
  unsigned_short_max = 0b1111111111111111
  unsigned_int_max = 0b11111111111111111111111111111111

  lo_mantissa = 0
  exponent = 16398
  hi_mantissa = i

  # TODO: for now write the integer portion of i
  while hi_mantissa < 44000
    hi_mantissa *= 2
    exponent -= 1
  end

  hi_mantissa = ((hi_mantissa & unsigned_int_max) << 16) & 
unsigned_int_max

  arr = [exponent, hi_mantissa >> 16, hi_mantissa & unsigned_short_max, 
lo_mantissa >> 16, lo_mantissa & unsigned_short_max]
  arr.pack("n5")
end

These are quick ugly hacks. Any help is appreciated, thanks. :)

/Anton

-- 
Posted via http://www.ruby-forum.com/.