Is there a reverse buffer function?

11 views (last 30 days)
Martin
Martin on 10 Oct 2013
Commented: Cedric 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
Cedric 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.

Sign in to comment.

Accepted Answer

Cedric
Cedric on 10 Oct 2013
Edited: Cedric 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.
  3 Comments
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
Cedric on 10 Oct 2013
Edited: Cedric 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.

Sign in to comment.

More Answers (0)

Products

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!