One of the examples in the excellent Erlang book shows how to decode an MPEG header, using Erlang's bit syntax. This is what it looks like:
decode_header(<<2#11111111111:11,B:2,C:2,_D:1,E:4,F:2,G:1,Bits:9>>) ->
Vsn = case B of
0 -> {2,5};
1 -> exit(badVsn);
2 -> 2;
3 -> 1
end,
Layer = case C of
0 -> exit(badLayer);
1 -> 3;
2 -> 2;
3 -> 1
end,
%% Protection = D,
BitRate = bitrate(Vsn, Layer, E) * 1000,
SampleRate = samplerate(Vsn, F),
Padding = G,
FrameLength = framelength(Layer, BitRate, SampleRate, Padding),
if
FrameLength < 21 ->
exit(frameSize);
true ->
{ok, FrameLength, {Layer,BitRate,SampleRate,Vsn,Bits}}
end;
decode_header(_) ->
exit(badHeader).
This is the same code, but then in Java, using Preon:
public class MpegHeader {
@BoundNumber(size="11", match="0b11111111111")
private int frameSync;
@BoundNumber(size="2")
private int mpegAudioVersionId;
@BoundNumber(size="2")
private int layerDescription;
@Bound
private boolean crcProtected;
@BoundNumber(size="4")
private int bitRateIndex;
@BoundNumber(size="2")
private int sampleRateFrequencyIndex;
@Bound
private boolean padded;
@Bound
private boolean privateBit;
@BoundNumber(size="2")
private int channelMode;
@BoundNumber(size="2")
private int modeExtension;
@Bound
private boolean copyright;
@Bound
private boolean original;
@BoundNumber(size="2")
private int emphasis;
}
Codeccodec = new Codecs.create(MpegHeader.class);
Codecs.decode(codec, buffer);
Now, there are obviously a lot of differences. The Erlang example also includes calls to functions defined elsewhere to determine the bitrate and frame lenght. The Preon example does not have that. If you would need it, you could imagine implementing it as methods of the MpegHeader class.
Also note that the example does match on the first 11 bits, expecting them to be ones only, similar to the Erlang example. The notation
@BoundNumber(size="11", match="0b11111111111") basically says that this field will be decoded from 11 input bits, as long as it matches the bit pattern "11111111111". Or to be more precise, as long as it matches the numeric value of 11 "1" bits, interpreted as an integer. If that criterion isn't met, the Codec will throw a DecodingException.I will try to work the other examples into Java with Preon examples as well, but it's interesting to see how the two approaches compare. What would you prefer? And why?
0 comments:
Post a Comment