Discover MakerZone

MATLAB and Simulink resources for Arduino, LEGO, and Raspberry Pi

Learn more

Discover what MATLAB® can do for your career.

Opportunities for recent engineering grads.

Apply Today

Is there a reverse buffer function?

Asked by Martin on 10 Oct 2013
Latest activity Commented on by Cedric Wannaz on 10 Oct 2013

I divided a sound data into smaller frames using buffer and a overlap of 50%. I applied a window function on the frames and want to merge it into one again. Is there any reverse buffer function?

Here's the basic idea:

x = randn(100,1);
x = buffer(x, 20, 10); % 20 frames with 50% overlap

This will result in a 20x10 double matrix.

The question now is: How do I merge the 20x10 matrix to a 100x1 vector again, where the overlap sections are added together?

EDIT: I just noticed that this is not what I wanted to do, huge error in reasoning. The solution is still correct though.

2 Comments

Cedric Wannaz on 10 Oct 2013

Do you always have a 50% overlap?

Martin on 10 Oct 2013

For this case my overlap is always 50%, yes.

Martin

Products

1 Answer

Answer by Cedric Wannaz on 10 Oct 2013
Edited by Cedric Wannaz on 10 Oct 2013
Accepted answer

If you always have these parameters, I guess that a solution is

 y = x(1:10,2:end) + x(11:20,1:end-1) ;
 y =[y(:); x(11:20,end)] ;

If the overlap is always 50% but the size of the initial data or the number of frames can vary, we can easily extend this solution.

To illustrate

 >> x = 1:20 ;
 >> x = buffer(x, 4, 2)
 x =
     0     1     3     5     7     9    11    13    15    17
     0     2     4     6     8    10    12    14    16    18
     1     3     5     7     9    11    13    15    17    19
     2     4     6     8    10    12    14    16    18    20

Then you process this array but I leave it as it is so we can check the next operation ..

 >> y = x(1:2,2:end) + x(3:4,1:end-1) ;
 >> y =[y(:); b(3:4,end)]
 y =
     2
     4
     6
     8
    10
    12
    14
    16
    18
    20
    22
    24
    26
    28
    30
    32
    34
    36
    19
    20

Here we see that all elements were doubled (expected for 50% overlap), but the last ones which had no overlap.

=== EDIT 1: here is one general solution (must be fully tested), which doesn't require 50% overlap. The idea is that we build a vector of IDs of elements of x that we buffer the same way as x. This provides us with the distribution of elements in buffers. We use these IDs then to reaggregate buffered data.

 x  = [0,1:15,0] ;                        % Some test data.
 % - Buffer.
 nf = 6 ;
 no = 2 ;
 xb = buffer( x, nf, no ) ;
 % - Apply some operation.
 % ...
 % - "Unbuffer".
 id  = 1:length( x ) ;                    % Vector of element IDs in x.
 idb = buffer( id, nf, no ) ;             % Buffer IDs the same way as x.
 rg  = no+1:no+nnz(idb) ;                 % Range for linear extraction of
                                          % relevant elements in xb and idb.
 y   = accumarray( idb(rg).', xb(rg) ) ;

Let me know if you want me to clarify anything about this solution. Note that I don't know the Fixed-point toolbox, so there might be a tool in this tbx for unbuffering that I am unaware of. The solution above is just using regular MATLAB operations.

3 Comments

Martin on 10 Oct 2013

How would a generic solution look like? When the dimensions of the matrices are not known, but you know the overlap is always 50%? I'm not 100% sure, I understand your approach correctly, but the solution of your example looks correct.

EDIT: Ok. I get the idea now. What is the b in this line though?

   y =[y(:); b(3:4,end)]

Wouldn't

y =[y(:)]

be sufficient?

Martin on 10 Oct 2013

I guess this would be the generic way:

y = x(1:size(x,1)/2,2:end) + x((size(x,1)/2)+1:size(x,1),1:end-1);
y = y(:);
Cedric Wannaz on 10 Oct 2013

See edit 1 above for a general solution.

About your edit, y(:) doesn't include the last n_overlap elements. The line

 y = x(1:2,2:end) + x(3:4,1:end-1) ;

sums two sub-blocks of the buffer

 | 0 [          block 1        ] |
 | 0 [                         ] |
 | [          block 2        ] 19|
 | [                         ] 20|

but we need to take the last 2 (in this case) elements which were not duplicated when we unbuffer, which is what

 y =[y(:); b(3:4,end)]

does.

Cedric Wannaz

Contact us