<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<meta content="text/html; charset=ISO-8859-1"
http-equiv="Content-Type">
<title></title>
</head>
<body text="#000000" bgcolor="#ffffff">
Paul<br>
<br>
Thank you for the explanations. I have data running right through
the app now using a simulator in Erlang pretending to be the
hardware. Next up is to plug in the DSP. I've done a linked-in
driver before so hoping that won't be too difficult. <br>
<br>
Bob<br>
<br>
On 23/03/2011 01:50, Per Gustafsson wrote:
<blockquote
cite="mid:AANLkTinruhUL_BV04m0Qti0eAavp1VEFkU75SFVP+qRh@mail.gmail.com"
type="cite">So essentially everytime this function is called one
of the four clauses will match
<div><br>
</div>
<div>1. Will match if the state is exactly a full block right now.
It will send that frame to the dsp module, and then it will
continue to decode the current frame using a new state.</div>
<div><br>
</div>
<div>2. If the current state is larger than a full block we will
split out the full block and send that to the dsp module, we
will then continue to decode the current frame using whatever
was left in the old state as the new state.</div>
<div><br>
</div>
<div>3. If the frame still has samples in it and neither of the
first two cases were true we will take out one set of samples,
convert to them to floats and add them to the end of the state
and continue to decode the rest of the frame.</div>
<div><br>
</div>
<div>4 If the frame is empty we will return the current state.</div>
<div><br>
</div>
<div>The difference between this version and the version that uses
a comprehension is that we are checking for every sample whether
the state is now a full frame or not.</div>
<div><br>
</div>
<div>This allows us to write the new samples directly into the
state binary, rather than creating a temporary binary. That we
then copy into the state binary.</div>
<div><br>
<br>
<div class="gmail_quote">2011/3/18 Bob Cowdery <span dir="ltr"><<a
moz-do-not-send="true"
href="mailto:bob@bobcowdery.plus.com" target="_blank">bob@bobcowdery.plus.com</a>></span><br>
<blockquote class="gmail_quote" style="margin: 0pt 0pt 0pt
0.8ex; border-left: 1px solid rgb(204, 204, 204);
padding-left: 1ex;">
<div text="#000000" bgcolor="#ffffff"> Humour me. I'm still
learning erlang and it still takes me ages to write a few
lines at times. Comments in-line.<br>
<br>
Bob
<div><br>
<br>
On 17/03/2011 20:54, Per Gustafsson wrote:
<blockquote type="cite"><font face="'courier new',
monospace">You're right it should be as below to get
the same behaviour, but I think it will work the
same for input that makes sense.</font>
<div><font face="'courier new', monospace"><br>
</font></div>
</blockquote>
</div>
Straight forward
<div><br>
<blockquote type="cite">
<div><font face="'courier new', monospace"> </font></div>
<div><font face="'courier new', monospace"> <span
style="border-collapse: collapse; font-size:
13px;">
<div style="color: rgb(80, 0, 80);">
do_decode_frame(Frame, State) -><br>
%% Separate the command bytes from the
frame data<br>
<<C1:8, C2:8, C3:8, C4:8, C5:8,
Rest/binary>> = Frame,<br>
</div>
decode_samples(Rest, State).</span></font></div>
<div><font face="'courier new', monospace"><span
style="border-collapse: collapse; font-size:
13px;"><br>
</span></font></div>
</blockquote>
</div>
First clause will match a full block where frames and
blocks are aligned. Never happen in practice as 63 will
never be a multiple of 64 but it's right that the code
should not know this.
<div><br>
<blockquote type="cite">
<div><font face="'courier new', monospace"><span
style="border-collapse: collapse; font-size:
13px;"> decode_samples(Frame, FullBlock) when
bytesize(FullBlock) == ?BinSize -><br>
dsp:process_block(FullBlock),<br>
decode_samples(Frame, <<>>);<br>
</span></font></div>
</blockquote>
</div>
Second clause will match when a FullBlock has > <font
face="'courier new', monospace"><span
style="border-collapse: collapse; font-size: 13px;"><span
style="font-family: arial,sans-serif;"><span
style="font-family: 'courier new',monospace;
color: rgb(0, 0, 0);">?BinSize and will split into
</span></span></span></font><font face="'courier
new', monospace"><span style="border-collapse: collapse;
font-size: 13px;"><span style="font-family:
arial,sans-serif;"><span style="font-family:
'courier new',monospace; color: rgb(0, 0, 0);">?BinSize
and Rest<br>
</span></span></span></font>
<div>
<blockquote type="cite">
<div><font face="'courier new', monospace"><span
style="border-collapse: collapse; font-size:
13px;"> <span style="font-family:
arial,sans-serif;">
<div style="color: rgb(80, 0, 80);"> <span
style="font-family: 'courier
new',monospace; color: rgb(0, 0, 0);">decode_samples(Frame,
<<FullBlock:?BinSize/binary,
Rest/binary>>) -><br>
dsp:process_block(FullBlock),<br>
decode_samples(Frame, Rest);</span></div>
</span></span></font></div>
</blockquote>
</div>
Third clause. Now I get lost. This will match pretty much
any binary > 8 bytes and any State. So this will get
called from first and second clause. The next two clauses
seem to run into each other. Don't understand that. Is the
binary comprehension hidden somewhere in there?
<div><br>
</div>
</div>
</blockquote>
<div><br>
</div>
<div>Sorry the third clause is totally wrong. It should have
been:<br>
<font face="'courier new', monospace"><span
style="border-collapse: collapse; font-size: 13px;">decode_samples(<<I:24/big-signed,
Q:24/big-signed, _M:16/big-signed, Rest/binary>>,
State) -><br>
decode_samples(Rest,
<<State/binary, (I/?S):32/float,
(Q/?S):32/float>>);</span></font><br>
</div>
<blockquote class="gmail_quote" style="margin: 0pt 0pt 0pt
0.8ex; border-left: 1px solid rgb(204, 204, 204);
padding-left: 1ex;">
<div text="#000000" bgcolor="#ffffff">
<div>
<blockquote type="cite">
<div><font face="'courier new', monospace"><span
style="border-collapse: collapse; font-size:
13px;">decode_samples(<<I:24/big-signed,
Q:24/big-signed, _M:16/big-signed,<br>
Rest/binary>>, State) -><br>
decode_samples(<<State/binary, (I/?S):32/float,
(Q/?S):32/float>>;<br>
decode_samples(<<>>, State) -><br>
{ok, State}.</span></font></div>
<div><font face="arial, sans-serif"><span
style="border-collapse: collapse;"><br>
</span></font></div>
</blockquote>
</div>
Would this work as the last two clauses:<br>
decode_samples(Frame, State) -><br>
decode_samples(<<>>, <<
State/binary, <<(I/?S):32/float,
(Q/?S):32/float>> || <<I:24/big-signed,
Q:24/big-signed, _M:16/big-signed>> <= Frame
>>)
<div>
<div><br>
decode_samples(<<>>, State) -><br>
{ok, State}.<br>
<blockquote type="cite">
<div><br>
2011/3/17 Bob Cowdery <<a
moz-do-not-send="true"
href="mailto:bob@bobcowdery.plus.com"
target="_blank">bob@bobcowdery.plus.com</a>>:<br>
> Thanks. More or less what I thought that the
only copy is in the append<br>
> operation. The one liner is the big one in
terms of time but I will<br>
> profile the whole thing eventually. I don't
think your solution does<br>
> quite the same thing as the sent block must
be exactly the correct size<br>
> not >= but I appreciate the kind of
structure you are using with small<br>
> clauses is more elegant.<br>
><br>
> Bob<br>
><br>
> On 17/03/2011 17:11, Per Gustafsson wrote:<br>
>> It will copy binaries, but essentially
the state binary will act like<br>
>> a growable array, pre-allocating space to
grow in, so there will be<br>
>> some copying , but it will be linear in
the size of the resulting<br>
>> array.<br>
>> It might be a little bit faster to
rewrite this as shown below. The<br>
>> reason I think this might be faster is
that you do not create a<br>
>> temporary samples array that just gets
copied. Whether this is faster<br>
>> or not in reality is of course a matter
of benchmarking.<br>
>><br>
>> %% Constants<br>
>> %% Input scale factor<br>
>> -define (S, (1 bsl 23) - 1).<br>
>> %% Block size for DSP (interleaved I and
Q)<br>
>> -define (BlockSz, 1024).<br>
>> %% Samples in a Metis frame (interleaved
I and Q)<br>
>> -define (MetisSmpls, 63).<br>
>> %% Bytes in a float<br>
>> -define (FloatSz, 4).<br>
>> %% Size of binary for given block size<br>
>> -define (BinSz,
?BlockSz*2*?FloatSz*?MetisSmpls).<br>
>><br>
>> do_decode_frame(Frame, State) -><br>
>> %% Separate the command bytes from the
frame data<br>
>> <<C1:8, C2:8, C3:8, C4:8, C5:8,
Rest/binary>> = Frame,<br>
>> decode_samples(Rest, State).<br>
>><br>
>> decode_samples(Frame, State) when
size(State) >= ?BinSz -><br>
>> dsp:process_block(State),<br>
>> decode_samples(Frame,
<<>>);<br>
>> decode_samples(<<I:24/big-signed,
Q:24/big-signed, _M:16/big-signed,<br>
>> Rest/binary>>, State) -><br>
>> decode_samples(<<State/binary,
(I/?S):32/float, (Q/?S):32/float>>;<br>
>> decode_samples(<<>>, State)
-><br>
>> {ok, State}.<br>
>><br>
>> 2011/3/17 Bob Cowdery <<a
moz-do-not-send="true"
href="mailto:bob@bobcowdery.plus.com"
target="_blank">bob@bobcowdery.plus.com</a>><br>
>>> Hi,<br>
>>><br>
>>> Am I correct in thinking that the
code fragments below will not copy any<br>
>>> binary data. I've not tested the
function yet so it may have bugs but<br>
>>> I'm interested in whether it will be
optimal in efficiency. State starts<br>
>>> off as an empty binary. Frames are
decoded and placed in a block. There<br>
>>> are not an integral number of frames
to a block. The function<br>
>>> dsp:process_block() is in another
gen-server.<br>
>>><br>
>>> Thanks<br>
>>> Bob<br>
>>><br>
>>> %% Constants<br>
>>> %% Input scale factor<br>
>>> -define (S, (1 bsl 23) - 1).<br>
>>> %% Block size for DSP (interleaved I
and Q)<br>
>>> -define (BlockSz, 1024).<br>
>>> %% Samples in a Metis frame
(interleaved I and Q)<br>
>>> -define (MetisSmpls, 63).<br>
>>> %% Bytes in a float<br>
>>> -define (FloatSz, 4).<br>
>>> %% Size of binary for given block
size<br>
>>> -define (BinSz,
?BlockSz*2*?FloatSz*?MetisSmpls).<br>
>>><br>
>>> do_decode_frame(Frame, State) -><br>
>>> %% Separate the command bytes from
the frame data<br>
>>> <<C1:8, C2:8, C3:8, C4:8,
C5:8, Rest/binary>> = Frame,<br>
>>> %% What's left now is
<<I:24, Q:24, M:16 ..repeated 63 times..
>><br>
>>> %% This one liner converts the I
and Q to scaled floats<br>
>>> Samples = <<
<<(I/?S):32/float, (Q/?S):32/float>>
||<br>
>>> <<I:24/big-signed,
Q:24/big-signed, _M:16/big-signed>> <=
Rest >>,<br>
>>> CurrentSz = size(State),<br>
>>> FrameSz = size(Samples),<br>
>>> if<br>
>>> (CurrentSz + FrameSz) <
?BinSz -><br>
>>> NewState =
<<State/binary, Samples/binary>>;<br>
>>> true -><br>
>>> %% Binary part of this
transfer<br>
>>> CutAt = ?BinSz - CurrentSz
- 1,<br>
>>> Bp = binary_part(Samples,
{0, CutAt}),<br>
>>> %% Binary part of
remainder<br>
>>> Br = binary_part(Samples,
{CutAt, FrameSz - CutAt}),<br>
>>> %% Process this block<br>
>>>
dsp:process_block(<<State/binary,
Bp/binary>>),<br>
>>> NewState = Br<br>
>>> end,<br>
>>> {ok, NewState}.<br>
>>><br>
>>>
________________________________________________________________<br>
>>> erlang-questions (at) <a
moz-do-not-send="true" href="http://erlang.org"
target="_blank">erlang.org</a> mailing list.<br>
>>> See <a moz-do-not-send="true"
href="http://www.erlang.org/faq.html"
target="_blank">http://www.erlang.org/faq.html</a><br>
>>> To unsubscribe; mailto:<a
moz-do-not-send="true"
href="mailto:erlang-questions-unsubscribe@erlang.org"
target="_blank">erlang-questions-unsubscribe@erlang.org</a><br>
>>><br>
><br>
><br>
<br>
</div>
</blockquote>
<br>
</div>
</div>
</div>
</blockquote>
</div>
<br>
</div>
</blockquote>
<br>
</body>
</html>