Asked by Martin
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.

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.

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?

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.

Opportunities for recent engineering grads.

## 2 Comments

## Cedric Wannaz (view profile)

Direct link to this comment:http://www.mathworks.com/matlabcentral/answers/89747#comment_173343

Do you always have a 50% overlap?

## Martin (view profile)

Direct link to this comment:http://www.mathworks.com/matlabcentral/answers/89747#comment_173398

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