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

New to MATLAB?

Is there a reverse buffer function?

Asked by Martin

Martin

on 10 Oct 2013
Latest activity Commented on by Cedric Wannaz

Cedric Wannaz

on 10 Oct 2013
Accepted Answer by Cedric Wannaz

Cedric Wannaz

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

Cedric Wannaz

on 10 Oct 2013

Do you always have a 50% overlap?

Martin

Martin

on 10 Oct 2013

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

Martin

Martin

Products

1 Answer

Answer by Cedric Wannaz

Cedric Wannaz

on 10 Oct 2013
Edited by Cedric Wannaz

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

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

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

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

Cedric Wannaz

Contact us