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

# 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.

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.

## Products

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

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?

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.