%% $RCSfile: sdspdsamp2.tlc,v $ %% $Revision: 1.3 $ $Date: 1999/12/16 23:55:58 $ %% %% Copyright (c) 1995-1999 The MathWorks, Inc. %% %% Abstract: Decreases the sampling rate of a signal %% by downsampling by an integer factor. %% Downsampling stars at specifid sample offset. %implements sdspdsamp2 "C" %include "dsplib.tlc" %% Function: BlockInstanceSetup =============================================== %% %function BlockInstanceSetup(block, system) void %% %% Block parameters: %assign INPORT = 0 %assign OUTPORT = 0 %assign block = block + INPORT + OUTPORT %assign cplx = (LibBlockInputSignalIsComplex(INPORT) != 0) %assign dtype = cplx ? "creal_T" : "real_T" %assign inWidth = CAST("Number",LibDataInputPortWidth(INPORT)) %assign outWidth = CAST("Number",LibDataOutputPortWidth(OUTPORT)) %assign numDims = LibBlockInputSignalNumDimensions(INPORT) %assign dims = LibBlockInputSignalDimensions(INPORT) %assign COLS = (numDims == 2) ? dims[1] : 1 %assign ROWS = dims[0] %assign isInputFrameBased = LibBlockInputSignalIsFrameData(INPORT) %assign nChans = isInputFrameBased ? COLS : inWidth %assign isEnforceSingleRate = CAST("Boolean",SFcnParamSettings.isEnforceSingleRate) %assign isMultiRate = !LibIsSFcnSingleRate(block) %assign isMultiTasking = IsModelMultiTasking() %assign convfactor = CAST("Number",SFcnParamSettings.DFACTOR[0]) %assign phase = CAST("Number",SFcnParamSettings.PHASE[0]) %assign SamplesPerInputFrame = CAST("Number", inWidth / nChans) %assign needICs = ( (!isInputFrameBased && isEnforceSingleRate) || \ (isMultiRate && !(!isInputFrameBased && (!isMultiTasking) && (phase == 0)))) %assign block = block + needICs + convfactor + \ isInputFrameBased + phase + cplx + \ isMultiRate + isMultiTasking + dtype + \ isEnforceSingleRate + inWidth + outWidth + \ SamplesPerInputFrame + nChans %% PWORKS: %if needICs %assign PWorklen = ((!isInputFrameBased && isEnforceSingleRate)) ? 1 : 2 %% %endif %if needICs %assign OUTBUF = 0 %assign INBUF = 1 %assign block = block + OUTBUF + INBUF %endif %endfunction %% BlockInstanceSetup %% Function: InitializeConditions ============================================= %% %% Abstract: %% %function InitializeConditions(block, system) Output /* DSP Blockset Down sample (%) - % */ %% %assign IC = SFcnParamSettings.IC %assign ic_cplx = TYPE(SFcnParamSettings.IC[0]) == "Complex" %assign dtype_ic = ic_cplx ? "creal_T" : "real_T" %assign ic_rows = SFcnParamSettings.IC_ROWS %assign ic_cols = SFcnParamSettings.IC_COLS %assign numIC = SIZE(SFcnParamSettings.IC,1) %% /* Reset counter */ % = %<(phase == 0) ? 0 : convfactor - phase>; %% %if needICs %% %% Save input/output pointers to buffer %% %assign buffer = LibBlockDWorkAddr(Buffer,"","", 0) %% /% Set the first PWork for all modes (that require latency) %/ % = %; %if isMultiRate /% Set the second PWork for the multi-rate mode only %/ % = % + %; %endif %% %% Fill in ICs into top portion of buffer: %% %% { %if numIC > 1 %% %% Number of ICs is greater than one, so we have to build up a variable. %% %assign astr = "" %assign count = 0 %if (ic_cplx) creal_T ic[%] = { %foreach Col = ic_cols %foreach Row = ic_rows %assign astr = astr + "{%,%}" %assign count = count + 1 %if (count < numIC) %assign astr = astr + "," %else %assign astr = astr + "};" %endif %endforeach % %assign astr = "" %endforeach %else real_T ic[%] = { %foreach Col = ic_cols %foreach Row = ic_rows %assign astr = astr + "%" %assign count = count + 1 %if (count < numIC) %assign astr = astr + "," %else %assign astr = astr + "};" %endif %endforeach % %assign astr = "" %endforeach %endif %endif %% % *outBuf; int i; %% %% The ICs must be filled in according to the outWidth %% because downsample causes the output to be smaller than %% the input when the mode forces sample rates equal. outBuf = %; for (i=0; i<%; i++) { %% %if (numIC <= 1) %% %if numIC == 0 %assign IC_re = 0.0 %assign IC_im = 0.0 %else %assign IC_re = REAL(IC[0]) %if !ic_cplx %assign IC_im = 0.0 %else %assign IC_im = IMAG(IC[0]) %endif %endif /* Scalar IC */ %if !cplx *outBuf++ = %; %else outBuf->re = %; (outBuf++)->im = %; %endif %else %% %% We are not using memcopy here because if the input %% is complex and the ic is real, we fill in the imaginary %% part with zeros. %% /* Vector IC */ %if !cplx *outBuf++ = ic[i]; %else outBuf->re = %<(ic_cplx) ? "ic[i].re" : "ic[i]">; (outBuf++)->im = %<(ic_cplx) ? "ic[i].im" : 0.0>; %endif %endif } %% end for outWidth } %endif %endfunction %% InitializeConditions %% Function: Outputs ========================================================== %% %function Outputs(block, system) Output /* DSP Blockset Downsample (%) - % */ %% %% %if !IsInputPortContiguous(block, 0) % %endif %% %% { %if !needICs %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %% NO ICs REQUIRED %% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% /* no ICs required */ % *y = (% *)(%); % *u = (% *)(%); int_T c; %% %if (nChans > 1) int_T n; for (n = 0; n < %; n++) { %endif %% c = %; /* Reset counter for each channel */ %% %if (SamplesPerInputFrame > 1) { int_T i; for (i=0; i<%; i++) { %endif %% if (c++ == 0) *y++ = *u++; else u++; if (c == %) c = 0; %% %if (SamplesPerInputFrame > 1) } } %endif %% %if (nChans > 1) } %endif %% % = c; /* Update counter for next sample hit */ %% %else %% %if (!isInputFrameBased && isEnforceSingleRate) %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %% SINGLE-RATE ENFORCED %% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% /* Single-rate enforced */ % *y = (% *)(%); % *u = (% *)(%); % *outBuf = (% *)(%); int_T c; %% %% %if (nChans > 1) int_T n; for (n = 0; n < %; n++) { %endif c = %; /* Reset counter for each channel */ if (c++ == 0) *outBuf = *u++; if (c == %) c = 0; *y++ = *outBuf++; %if (nChans > 1) } %endif % = c; /* Update counter for next sample hit */ %% %% %else if (%) { %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %% OUTPUT HIT %% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% /* output hit */ % *y = (% *)(%); % *outBuf = (% *)(%); %% %if outWidth > 1 int_T i = %; while(i-- > 0) { %endif *y++ = *outBuf++; %if outWidth > 1 } %endif %% %% Always update pointer: %% /* Update Output pointer buffer */ { % *aBuf = (% *)(%); if (outBuf == aBuf + %<2*outWidth>) { outBuf = aBuf ; } % = outBuf; } %% } if (%) { %if isInputFrameBased %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %% INPUT HIT: FRAME BASED %% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% /* Input hit: Frame-based */ % *u = (% *)(%); % *inBuf; int_T c; %% %if (nChans > 1) int_T n; for (n = 0; n < %; n++) { %endif /* Point to current channel */ %if (nChans > 1) inBuf = (% *)(%) + n*%; %else inBuf = (% *)(%); %endif c = %; /* Reset counter for each channel */ %if (SamplesPerInputFrame > 1) { int_T i; for (i=0; i<%; i++) { %endif if (c++ == 0) *inBuf++ = *u++; else u++; if (c == %) c = 0; %if (SamplesPerInputFrame > 1) } } %endif %if (nChans > 1) } %endif %% %% % = c; /* Update counter for next sample hit */ %% /* Update input pointer buffer */ { % *aBuf = (% *)(%); if (inBuf == aBuf + %<2*outWidth>) { inBuf = aBuf; } else if (inBuf != aBuf + %) { inBuf -= %<(nChans-1)*SamplesPerInputFrame>; } % = inBuf; } %% %else %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %% INPUT HIT: SAMPLE BASED %% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% /* Input hit: Sample-based */ %% % *u = (% *)(%); % *inBuf = (% *)(%); int_T c; %% %% %if (nChans > 1) int_T n; for (n = 0; n < %; n++) { %endif c = %; /* Reset counter for each channel */ if (c++ == 0) *inBuf++ = *u++; else u++; if (c == %) c = 0; %if (nChans > 1) } %endif % = c; /* Update counter for next sample hit */ /* Update input pointer buffer */ { % *aBuf = (% *)(%); if (inBuf == aBuf + %<2*outWidth>) { inBuf = aBuf; } % = inBuf; } %endif %% frame-based input } %endif %% enforce single rate %endif %% need ICs } %endfunction %% [EOF] sdspdsamp2.tlc