Binary no-copy

Bob Cowdery <>
Thu Mar 17 17:05:51 CET 2011


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.


%% 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),
        (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
    {ok, NewState}.

More information about the erlang-questions mailing list