Is there a reverse buffer function?
11 views (last 30 days)
Show older comments
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
Accepted Answer
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
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.
More Answers (0)
See Also
Categories
Find more on Logical in Help Center and File Exchange
Products
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!