Bitstuct and binary files

R

Rob Lee

Hi,

I've been working with modifying a binary file to replace some meta-data
included within. I've had some discussions previously
(http://www.ruby-forum.com/topic/85591) about this but couldn't get to a
satisfactory conclusion. Basically I need to encode an integer value
into 3 bytes as part of a binary file - Bitstruct was suggested as one
of the solutions, however I haven't been able to get it to work for
values larger than 1024 :

require 'bit-struct'

class Audio < BitStruct
signed :aheader, 8, :endian => :little
unsigned :alength, 3*8, :endian => :little
signed :afooter, 8, :endian => :little
end

audio = Audio.new
audio.aheader = 1
audio.alength = 3027
audio.afooter = 1
f = open("testfile","wb")
f.write(audio)
f.close
f = open("testfile","rb")
f.pos=0
puts f.read(1).unpack("c").first.to_s
puts f.read(3).unpack('H6').first.to_i(16)
puts f.read(1).unpack("c").first.to_s
f.close

In the application above, if the value of audio.alength is set to equal
or below 1024 then the output for f.read(3).unpack('H6').first.to_i(16)
matches, however if set above this then the value printed doesn't match.

Can anybody tell me why setting an audio.alength>=1024 breaks the output
and provide a way to fix it ...

Thanks
 
J

Joel VanderWerf

Rob said:
puts f.read(3).unpack('H6').first.to_i(16)

I think you want 'h' instead of 'H', and you need to reverse the nibbles:

puts f.read(3).unpack('h6').first.reverse.to_i(16)
 
B

Ben Nagy

-----Original Message-----
[...]
Can anybody tell me why setting an audio.alength>=1024 breaks
the output
and provide a way to fix it ...

---borked---
num=359447
f.write(num.to_s(16)[0..2].instance_eval {(self.reverse + '0' * (6 -
self.length)).reverse}.scan(/../).inject('') {|s,byte| s <<
byte.to_i(16)})
---

My code is broken. Where I said [0..2] I meant [0..5], I added it in at the
last minute as an overflow check without testing - I was thinking 3 raw hex
bytes but the string after the conversion is a 6 byte 'friendly' hex string.

Sorry. :(

ben
 
R

Rob Lee

Joel said:
I think you want 'h' instead of 'H', and you need to reverse the
nibbles:

puts f.read(3).unpack('h6').first.reverse.to_i(16)

Ah, OK that works with my example script - thanks. However, that means
the Bitstruct definition I gave is incorrect. The binary file I'm
trying to modify correctly unpacks the integer using :

f.read(3).unpack('H6').first.to_i(16)

However, I'm really confused over what the Bitstruct definition should
be to support this - do you have any suggestions ?

Thanks
 
R

Rob Lee

My code is broken. Where I said [0..2] I meant [0..5], I added it in at
the
last minute as an overflow check without testing - I was thinking 3 raw
hex
bytes but the string after the conversion is a 6 byte 'friendly' hex
string.

Sorry. :(

ben

No problem ! I've just modified the code and it works great - thanks :)
I'm investigating bitstruct as well but it's always nice to have
alternatives ...
 
J

Joel VanderWerf

Rob said:
Ah, OK that works with my example script - thanks. However, that means
the Bitstruct definition I gave is incorrect. The binary file I'm
trying to modify correctly unpacks the integer using :

f.read(3).unpack('H6').first.to_i(16)

However, I'm really confused over what the Bitstruct definition should
be to support this - do you have any suggestions ?

Thanks

Then probably your data is in big endian order--I should have grokked
that from your code. Try this:

class Audio < BitStruct
signed :aheader, 8
unsigned :alength, 3*8
signed :afooter, 8
end
 
R

Rob Lee

Then probably your data is in big endian order--I should have grokked
that from your code. Try this:

class Audio < BitStruct
signed :aheader, 8
unsigned :alength, 3*8
signed :afooter, 8
end

Excellent - thank you. It all works - if you're interested I'm working
on a Ruby proxy for the Nabaztag (wifi bunny rabbit) and I'm trying to
extend some of it's audio capabilities :)
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,995
Messages
2,570,228
Members
46,818
Latest member
SapanaCarpetStudio

Latest Threads

Top