Binary no-copy
Bob Cowdery
bob@REDACTED
Thu Mar 17 17:05:51 CET 2011
Hi,
Am I correct in thinking that the code fragments below will not copy any
binary data. I've not tested the function yet so it may have bugs but
I'm interested in whether it will be optimal in efficiency. State starts
off as an empty binary. Frames are decoded and placed in a block. There
are not an integral number of frames to a block. The function
dsp:process_block() is in another gen-server.
Thanks
Bob
%% Constants
%% Input scale factor
-define (S, (1 bsl 23) - 1).
%% Block size for DSP (interleaved I and Q)
-define (BlockSz, 1024).
%% Samples in a Metis frame (interleaved I and Q)
-define (MetisSmpls, 63).
%% Bytes in a float
-define (FloatSz, 4).
%% Size of binary for given block size
-define (BinSz, ?BlockSz*2*?FloatSz*?MetisSmpls).
do_decode_frame(Frame, State) ->
%% Separate the command bytes from the frame data
<<C1:8, C2:8, C3:8, C4:8, C5:8, Rest/binary>> = Frame,
%% What's left now is <<I:24, Q:24, M:16 ..repeated 63 times.. >>
%% This one liner converts the I and Q to scaled floats
Samples = << <<(I/?S):32/float, (Q/?S):32/float>> ||
<<I:24/big-signed, Q:24/big-signed, _M:16/big-signed>> <= Rest >>,
CurrentSz = size(State),
FrameSz = size(Samples),
if
(CurrentSz + FrameSz) < ?BinSz ->
NewState = <<State/binary, Samples/binary>>;
true ->
%% Binary part of this transfer
CutAt = ?BinSz - CurrentSz - 1,
Bp = binary_part(Samples, {0, CutAt}),
%% Binary part of remainder
Br = binary_part(Samples, {CutAt, FrameSz - CutAt}),
%% Process this block
dsp:process_block(<<State/binary, Bp/binary>>),
NewState = Br
end,
{ok, NewState}.
More information about the erlang-questions
mailing list