📄 circbuff.m
字号:
classdef circBuff < handle
% circBuff is the class definition....
% ==================================================
% DATA MEMBERS
% ==================================================
properties (SetAccess='private')
buffer
wPtr
rPtr
bufferSize
blockLength
dataType
currSize
end
% ==================================================
% PRIVATE METHODS
% ==================================================
methods (Access='private')
end
% ==================================================
% PUBLIC METHODS
% ==================================================
methods
% constructor
function b =circBuff(bufferSize,dataType,blockLength)
% Constructs a circular buffer object.
% bH = circBuff(bufferSize, dataType, blockLength) constructs a circular
% buffer with length bufferSize. dataType is the data type for the buffer.
% 'complex' is accepted and empolys 'double' for its components. Block length
% shows the block length of the data that will be used for reading and aligning.
%
% bH.write(inData) writes inData to buffer. inData must be a column.
%
% [matchfrac, rPtr, wPtr, selBlock] = bH.align(refBlock, matchFraction) alligns the buffer based
% on the reference block column. If there is matchFraction (between 0 and 1) match between a
% bH.blockLength consecutive data in the buffer and refBlock, the read pointer of the buffer
% (bH.rPtr) is adjusted accordingly. it returns the measured match fraction, as well as the next
% read and write pointers and the selected block.
%
% [...] = bH.align(refBlock, matchFraction, sync) when sync==1 performs the
% alignment search in the buffer with a step equal to block length.
%
% [matchfrac, ...] = bH.align(refBlock, matchFraction, sync, euclid) when euclid==1
% searches for the minimum euclidean distance. matchFraction becomes the upper threshold
% for normalized euclidean distance, e'*e/(refBlock'*refBlock), where e is the error vector.
%
% [...] = bH.align(refBlock, matchFraction, sync, euclid, w) when euclid==1
% minimizes the weighted error power sum(w.*abs(e).^2) for a real vector of blockLength length.
%
% dataOut = bH.read returns a single block. must be called after a successful align.
% dataOut = bH.read(n) returns n blocks.
b.dataType = dataType;
if strcmpi(dataType, 'complex')==1
eval(sprintf('b.buffer = zeros(%.0f,1) + i*zeros(%.0f,1);', bufferSize, bufferSize));
else
eval(['b.buffer = ' dataType '(zeros(' num2str(bufferSize) ',1));']);
end;
b.wPtr = -1;
b.rPtr = -1;
b.bufferSize = bufferSize;
b.blockLength = blockLength;
b.currSize = 0;
end
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%%%% METHOD WRITE %%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
function write(b,inData)
if (b.wPtr == -1)
b.wPtr = 1;
end
if (b.wPtr + length(inData)-1) <= b.bufferSize
b.buffer(b.wPtr:b.wPtr + length(inData)-1) = inData;
else
b.buffer(b.wPtr:end) = inData(1:b.bufferSize-b.wPtr+1);
b.buffer(1:length(inData)-b.bufferSize+b.wPtr-1) = inData(b.bufferSize-b.wPtr+2:end);
end
b.wPtr = mod(b.wPtr + length(inData)-1,b.bufferSize)+1;
b.currSize = b.currSize + length(inData);
end
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%%%% METHOD READ %%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
function dataOut = read(b, nBlks)
if b.rPtr == -1
error('Please allign the buffer before reading');
end
if nargin<2
nBlks = 1;
end;
if b.rPtr+nBlks*b.blockLength-1 <= b.bufferSize
dataOut = b.buffer(b.rPtr:b.rPtr+nBlks*b.blockLength-1);
else
dataOut = [b.buffer(b.rPtr:end); b.buffer(1:b.rPtr+nBlks*b.blockLength-1 - b.bufferSize)];
end
b.rPtr = mod(b.rPtr + nBlks*b.blockLength-1, b.bufferSize) + 1;
b.currSize = b.currSize - nBlks*b.blockLength;
end
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%%%% METHOD ALIGN %%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
function [matchfrac, rPtr, wPtr, selBlock] = align(b, refBlock, matchFraction, sync, euclid, w)
if b.wPtr ==-1
error('Please write data to buffer before alignment');
end
if nargin<4 || sync==0
step = 1;
else
step = b.blockLength;
end;
if nargin<5
euclid = 0;
end;
if strcmpi(b.dataType, 'complex')
currentBlock = zeros(b.blockLength, 1) + i*zeros(b.blockLength, 1);
else
currentBlock = zeros(b.blockLength, 1);
end;
matchCnt = zeros(1,length(1:step:b.bufferSize));
for cnt=0:step:b.bufferSize-1
if cnt+b.blockLength <= b.bufferSize
currentBlock = b.buffer(cnt+(1:b.blockLength));
else
currentBlock(1: b.bufferSize-cnt) = b.buffer(cnt+1:end);
currentBlock(b.bufferSize-cnt+1:end) = b.buffer(1:b.blockLength-b.bufferSize+cnt);
end
if euclid==0
matchCnt(cnt/step+1)= sum(currentBlock==refBlock);
else
e = currentBlock-refBlock;
if nargin>=6
matchCnt(cnt/step+1) = sum(w.*abs(e).^2);
else
matchCnt(cnt/step+1) = real(e'*e);
end;
end;
end
if euclid==0
[match ind] = max(matchCnt);
matchStart0 = (ind-1)*step;
matchfrac = match/b.blockLength;
if matchfrac>=matchFraction
selBlock = b.buffer(mod(matchStart0 + (0:b.blockLength-1), b.bufferSize)+1);
b.rPtr = mod(matchStart0 + b.blockLength, b.bufferSize) + 1;
else
selBlock = [];
end
else
[match ind] = min(matchCnt);
matchStart0 = (ind-1)*step;
if nargin>=6
matchfrac = match/sum(w.*abs(refBlock).^2);
else
matchfrac = match/real(refBlock'*refBlock);
end;
if matchfrac<=matchFraction
selBlock = b.buffer(mod(matchStart0 + (0:b.blockLength-1), b.bufferSize)+1);
b.rPtr = mod(matchStart0 + b.blockLength, b.bufferSize) + 1;
else
selBlock = [];
end
end;
rPtr = b.rPtr;
wPtr = b.wPtr;
end
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%%%% METHOD RESET %%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
function reset(b)
b.wPtr = -1;
b.rPtr = -1;
end
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%%%% METHOD setReadPtr %%%%%%%%%%%%%%%%%%%%%%%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
function setReadPtr(b,ptr)
b.rPtr = ptr;
end
end
end
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -