Is there a reverse buffer function?

조회 수: 7 (최근 30일)
Martin
Martin 2013년 10월 10일
댓글: Cedric 2013년 10월 10일
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
Cedric
Cedric 2013년 10월 10일
Do you always have a 50% overlap?
Martin
Martin 2013년 10월 10일
For this case my overlap is always 50%, yes.

댓글을 달려면 로그인하십시오.

채택된 답변

Cedric
Cedric 2013년 10월 10일
편집: Cedric 2013년 10월 10일
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
Martin
Martin 2013년 10월 10일
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 2013년 10월 10일
편집: Cedric 2013년 10월 10일
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.

댓글을 달려면 로그인하십시오.

추가 답변 (0개)

카테고리

Help CenterFile Exchange에서 Multidimensional Arrays에 대해 자세히 알아보기

제품

Community Treasure Hunt

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

Start Hunting!

Translated by