%% $Revision: 1.15 $ %% $RCSfile: sbufferc.tlc,v $ %% $Date: 2000/04/06 17:26:24 $ %% %% Don Orofino, 07-Jul-97 %% Copyright (c) 1995-1999 The MathWorks, Inc. All Rights Reserved. %% %% Abstract: Target file for the S-Function sbufferc.c %% %implements "sbufferc" "C" %% Function: BlockInstanceSetup =============================================== %% %% Abstract: %% Rename the S-Function parameter for easy reference. %% %function BlockInstanceSetup(block, system) void %% % % % % %% % %% % % % % %% % % %% %endfunction %% BlockInstanceSetup %% Function: InitializeConditions ============================================= %% %% Abstract: %% Initialize the RWork vector (Buffer) to the initial values specified. %% Note that the IWork is memset to zero in the registration function, %% however we need to initialize it to zero again here, because this block %% might be used inside an enabled subsystem that resets on disable. %% %function InitializeConditions(block, system) Output /* % Block: % (%) */ { %assign nChans = LibDataInputPortWidth(0) %assign N = CAST("Number", LibBlockParameterValue(Buffer_Size, 0)) %assign VV = CAST("Number", LibBlockParameterValue(Buffer_Overlap, 0)) %% %if VV <= 0 %assign circBuf_len = 2 * N %assign newSPB = N %else %assign circBuf_len = 2 * N - VV %assign newSPB = N - VV %endif %% real_T *circBuf = &%; real_T *outBuf = circBuf + %; % = (void *)circBuf; % = (void *)outBuf; %assign sizIC = SIZE(Init_Cond.Value) %assign numIC = sizIC[0]*sizIC[1] /* Preset initial output buffers to initial conditions: */ { %if nChans > 1 int_T i; %endif %% %if numIC <= 1 %% /* Scalar expansion, or no IC's given: */ %if numIC == 0 %assign icScalar = 0.0 %else %assign icScalar = LibBlockMatrixParameter(Init_Cond,"","",0,"","",0) %endif %% %if nChans > 1 for(i = 0; i < %; i++) { %endif %% %if N > 1 %% Usual case: buffer has N>1 real_T *p = outBuf; int_T j; for (j = 0; j < %; j++) { *p++ = %; } %else %% Special case: buffer with 1 element %% (Keep one sample, then skip a bunch ... so usually V<0 as well) *outBuf++ = %; %endif %if nChans > 1 outBuf += %; } %endif %elseif numIC == N %% /* Same IC's for all channels: */ const real_T *pIC = %; %% %if nChans > 1 for(i = 0; i < %; i++) { %endif %% memcpy(outBuf, pIC, %*sizeof(real_T)); %% %if nChans > 1 outBuf += %; } %endif %else %% /* Matrix of IC's: */ const real_T *pIC = %; %% %if nChans > 1 for(i = 0; i < %; i++) { %endif %% memcpy(outBuf, pIC, %*sizeof(real_T)); %% %if nChans > 1 pIC += %; outBuf += %; } %endif %endif } % = 0; % = %; % = %; % = %; } %endfunction %% InitializeConditions %% Function: Outputs ========================================================== %% %% Abstract: %% %function Outputs(block, system) Output /* % Block: % (%) */ { %assign nChans = LibDataInputPortWidth(0) %assign N = CAST("Number", LibBlockParameterValue(Buffer_Size, 0)) %assign VV = CAST("Number", LibBlockParameterValue(Buffer_Overlap, 0)) %% %assign circBuf_len = (VV <= 0) ? 2*N : 2*N-VV %assign num_Ts = SIZE(TID, 1) %% %if num_Ts == 1 %% If there is 1 sample time, this gets executed the minimum # of times: real_T *circBuf = &%; %endif %% %if num_Ts > 1 if (%) { %endif %% /* Output next buffer: */ real_T *outBuf = %; %% %if num_Ts == 2 %% For two sample times, move this definition here: real_T *circBuf = &%; %endif %% real_T *y = %; int_T cnt = circBuf - (outBuf - %); /* # samples from outBuf to end of buffer */ if (cnt >= %) { /* Output buffer is one contiguous chunk: */ %% %if nChans==1 %% Single input channel: memcpy(y, outBuf, %*sizeof(real_T)); %else %% Multiple input channels: real_T *p = outBuf; int_T i; for(i=0; i<%; i++) { memcpy(y, p, %*sizeof(real_T)); y += %; p += %; } %endif %% outBuf = (cnt == %) ? circBuf : outBuf + %; } else { /* Output buffer is split into two chunks: */ %% %if nChans==1 %% Single input channel: memcpy(y, outBuf, cnt*sizeof(real_T)); memcpy(y+cnt, circBuf, (%-cnt)*sizeof(real_T)); %else %% Multiple input channels: real_T *pout = outBuf; real_T *pcirc = circBuf; int_T i; for(i=0; i < %; i++) { memcpy(y, pout, cnt*sizeof(real_T)); memcpy(y+cnt, pcirc, (%-cnt)*sizeof(real_T)); y += %; pout += %; pcirc += %; } %endif %% outBuf = circBuf + (%-cnt); } %% %if VV > 0 /* Bump output buffer pointer for overlap: */ outBuf -= %; /* Backup for overlap */ if (outBuf < circBuf) { outBuf += %; } %endif % = (void *)outBuf; %if num_Ts > 1 } %endif } %endfunction %% Outputs %% Function: Update ========================================================== %% %% Abstract: %% %function Update(block, system) Output /* % Block: % (%) */ { %assign nChans = LibDataInputPortWidth(0) %assign N = CAST("Number", LibBlockParameterValue(Buffer_Size, 0)) %assign VV = CAST("Number", LibBlockParameterValue(Buffer_Overlap, 0)) %% %assign circBuf_len = (VV <= 0) ? 2*N : 2*N-VV %assign num_Ts = SIZE(TID, 1) %% %if num_Ts == 1 %% If there is 1 sample time, this gets executed the minimum # of times: real_T *circBuf = &%; %endif %% %if num_Ts > 1 if (%) { %elseif VV < 0 { %endif %% /* Acquire input sample: */ %if VV < 0 boolean_T acquire_samples = 1; /* Handle underlap: */ { int_T *ul_count = &%; ++(*ul_count); /* skip this sample because of negative overlap */ if (*ul_count > %) { %if VV == -1 %% We don't need to make another test: *ul_count = 0; /* 1-point underlap */ %else if (*ul_count == %) { /* %<-VV>-point underlap */ *ul_count = 0; } %endif acquire_samples = 0; /* Skip acquisition */ } } %endif %% VV < 0 %% %% Acquire samples into buffer: %% %if VV < 0 if (acquire_samples) { %else { %endif /* Store the latest sample: */ %% %if num_Ts == 2 %% For two sample times, move this definition here: real_T *circBuf = &%; %endif %% real_T *inBuf = (real_T *) %; %% %if nChans==1 %% Single input channel: *inBuf++ = %; %else %% Multiple input channels: { real_T *p = inBuf++; %assign rollVars = ["U"] %roll sigIdx = RollRegions, lcv = RollThreshold, block,... "Roller", rollVars *p = %; p += %; %endroll } %endif /* * If we have reached the end of the circular buffer, * reset the input buffer index: */ if (inBuf == circBuf + %) { inBuf = circBuf; } % = (void *)inBuf; } %% %if (num_Ts > 1) || (VV < 0) } %endif } %endfunction %% Update %% EOF: sbufferc.tlc