%% $RCSfile: sdspadyad.tlc,v $ %% $Revision: 1.12 $ %% $Date: 2000/06/15 20:37:38 $ %% %% Copyright 1995-2000 The MathWorks, Inc. %% %% Abstract: Dyadic analysis filter bank %% %implements sdspadyad "C" %include "dsplib.tlc" %% Function: BlockInstanceSetup =============================================== %% %function BlockInstanceSetup(block, system) void %% Block does not support discontiguous inputs %if (!IsInputPortContiguous(block,0)) % %endif %assign INPORT = 0 %assign INPORTWIDTH = LibDataInputPortWidth(INPORT) %assign IN_COMPLEX = LibBlockInputSignalIsComplex(INPORT) %% All outputs are same complexity %assign OUT_COMPLEX = LibBlockOutputSignalIsComplex(0) %assign LFILT = SFcnParamSettings.LFILT %assign HFILT = SFcnParamSettings.HFILT %assign LP_LENGTH = CAST("Number", SIZE(SFcnParamSettings.LFILT,0) * SIZE(SFcnParamSettings.LFILT,1)) %assign HP_LENGTH = CAST("Number", SIZE(SFcnParamSettings.HFILT,0) * SIZE(SFcnParamSettings.HFILT,1)) %assign LP_ORDER = LP_LENGTH - 1 %assign HP_ORDER = HP_LENGTH - 1 %assign LSTART = LP_LENGTH - LP_LENGTH / 2 %assign HSTART = HP_LENGTH - HP_LENGTH / 2 %assign FILT_COMPLEX = TYPE(SFcnParamSettings.LFILT[0]) == "Complex" %assign FILT_LEVEL = 1 %% default %assign TREE = SFcnParamSettings.TREE %assign ASYMMETRIC = 1 %assign SYMMETRIC = 2 %assign NUM_LEVELS = SFcnParamSettings.LEVELS %assign NUM_CHANS = SFcnParamSettings.NUM_CHANS %assign SAMPLE_BASED = (NUM_CHANS == -1) %assign NUM_CHANS = (SAMPLE_BASED) ? INPORTWIDTH : NUM_CHANS %if (TREE == ASYMMETRIC) %assign NUM_FILTERS = 2 * NUM_LEVELS %else %assign FILT_LEVEL = 2 %assign NUM_FILTERS = 2 %foreach II = NUM_LEVELS-1 %assign FILT_LEVEL = FILT_LEVEL * 2 %assign NUM_FILTERS = NUM_FILTERS + FILT_LEVEL %endforeach %endif %assign OUTBUFF_SIZE = LibBlockDWorkWidth(OutBuff) / 2 %assign LPBUFFSIZE = LibBlockDWorkWidth(FiltBuff) / 2 %assign DAT_T = (IN_COMPLEX) ? "creal_T" : "real_T" %assign FILT_T = (FILT_COMPLEX) ? "creal_T" : "real_T" %assign OUT_T = (OUT_COMPLEX) ? "creal_T" : "real_T" %assign block = block + INPORT + INPORTWIDTH + IN_COMPLEX + OUT_COMPLEX + \ LFILT + HFILT + LP_LENGTH + HP_LENGTH + LP_ORDER + HP_ORDER + LSTART + HSTART + \ FILT_COMPLEX + FILT_LEVEL + TREE + ASYMMETRIC + SYMMETRIC + \ NUM_LEVELS + NUM_CHANS + SAMPLE_BASED + NUM_FILTERS + \ OUTBUFF_SIZE + LPBUFFSIZE + DAT_T + FILT_T + OUT_T %endfunction %% BlockInstanceSetup %% Function: InitializeConditions ============================================= %% %% Initialize the DWork vector (Buffer) to the initial values specified. %% %function InitializeConditions(block, system) Output { /* % Block: % (%) */ /* Initialize the counters. */ %% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %% Set up Filter Coefficients %% { /* Filter coefficients */ %assign astr = "" %assign count = 0 %if (FILT_COMPLEX) static creal_T lfilt[%] = { %foreach Idx = LP_LENGTH %assign astr = astr + "{%,%}" %assign count = count + 1 %if (count < LP_LENGTH) %assign astr = astr + "," %else %assign astr = astr + "};" %endif %if (count % 2 == 0 || count == LP_LENGTH) % %assign astr = "" %endif %endforeach %assign count = 0 static creal_T hfilt[%] = { %foreach Idx = HP_LENGTH %assign astr = astr + "{%,%}" %assign count = count + 1 %if (count < HP_LENGTH) %assign astr = astr + "," %else %assign astr = astr + "};" %endif %if (count % 2 == 0 || count == HP_LENGTH) % %assign astr = "" %endif %endforeach %else static real_T lfilt[%] = { %foreach Idx = LP_LENGTH %assign astr = astr + "%" %assign count = count + 1 %if (count < LP_LENGTH) %assign astr = astr + "," %else %assign astr = astr + "};" %endif %if (count % 4 == 0 || count == LP_LENGTH) % %assign astr = "" %endif %endforeach %assign count = 0 static real_T hfilt[%] = { %foreach Idx = HP_LENGTH %assign astr = astr + "%" %assign count = count + 1 %if (count < HP_LENGTH) %assign astr = astr + "," %else %assign astr = astr + "};" %endif %if (count % 4 == 0 || count == HP_LENGTH) % %assign astr = "" %endif %endforeach %endif % = hfilt; % = lfilt; /* Initialize pointers to filter coefficients so that they correspond to the * last filter phase. */ %if NUM_FILTERS > 1 { int_T k = 0; %roll sigIdx1 = [ 0:% ], lcv1 = 2, block, "InlineRoller" % = hfilt + %; % = lfilt + %; %endroll %% FILTERS } %else % = hfilt + %; % = lfilt + %; %endif } %% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %% Compute Latency properties and set counters appropriately %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %assign isSingleRate = LibIsSFcnSingleRate(block) %assign isMultiTasking = IsModelMultiTasking() %% %if(isSingleRate) /* SingleRate */ %assign out_offset = 1 %else /* MultiRate */ %assign out_offset = 0 %% %% Possible rewrite of code needed. A simple offset to %% the pointer index will not give correct behavior. The %% below is true for both Symmetric and Asymmetric cases. %% %if(!isMultiTasking) /* SingleTasking */ %% %% SingleTasking will have no latency %% when this portion of code is added. %% %else /* MultiTasking */ %% %% MultiTasking will have an initial latency of one simulation step %% when this portion of code is added. %% % %% %endif %endif %% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % = 0; %if (TREE == ASYMMETRIC) %assign rollVars = ["/InIdx", "/PhaseIdx", "/WrBuff1", "/OutIdx"] %else %assign rollVars = ["/InIdx", "/PhaseIdx"] %endif %% %roll sigIdx1 = [ 0:% ], lcv1 = 2, block, "Roller", rollVars % = 0; /* Start with the last phase at each level */ % = 1; %if (TREE == ASYMMETRIC) % = 1; % = %; %endif %endroll %% Levels %% %if (TREE == ASYMMETRIC) % = % ; %else % = % ; % = 1; %endif %% %assign rollVars = ["/MemIdx"] %roll sigIdx1 = [ 0:% ], lcv1 = 2, block, "Roller", rollVars % = 0; %endroll } %endfunction %% Function: InitOutBuffer ========================================================== %% %function InitOutBuffer(block) Output %assign outBuffSize = LibBlockDWorkWidth(OutBuff) /* Initialize Output Buffer */ { int_T i; int_T outBuffSize = %; for(i=0; i0")> = 0.0; %0")> = 0.0; %else % = 0.0; %endif } } %endfunction %% InitOutBuffer %% Function: Outputs ========================================================== %% %function Outputs(block, system) Output % % %endfunction %% Outputs %% Function: UpdateCode ========================================================== %% %function UpdateCode(block, system) Output %% %assign FRAME = (SAMPLE_BASED) ? 1 : (INPORTWIDTH / NUM_CHANS) { /* % Block: % (%) */ /* Update buffers */ % *cffHBase = (% *) %; % *cffLBase = (% *) %; %if !LibIsSFcnSingleRate(block) if (%) { %endif % *uptr = %; %if (SAMPLE_BASED) boolean_T ok = 0; { /* We delay processing until we buffer the minimum number of samples * that are required to generate an entire output frame. */ % *inBuff = %; int_T iIdx = %; %assign minFrame = 2 %foreach II = NUM_LEVELS-1 %assign minFrame = minFrame * 2 %endforeach %roll sigIdx1 = [ 0:% ], lcv1 = 2, block, "InlineRoller" %if (!IN_COMPLEX && FILT_COMPLEX) (inBuff+iIdx)->re = *uptr++; (inBuff+iIdx)->im = (real_T) 0.0; %else *(inBuff+iIdx) = *uptr++; %endif %if (NUM_CHANS > 1) inBuff += %; %endif %endroll if (++(%) == %) { ok = 1; %assign FRAME = minFrame % = 0; } } if (ok) { /* We have enough samples to process */ %else { %endif %% SAMPLE_BASED % *lpBuff0 = %; % *mem0 = %; % *sums = %; % *out = %; %roll sigIdx1 = [ 0:% ], lcv1 = 2, block, "InlineRoller" % *inBuff = %; int_T numSamps = %; % *lpBuff = lpBuff0; int_T filtIdx = 0; %if (!SAMPLE_BASED) %roll sigIdx2 = [ 0:% ], lcv2 = 2, block, "InlineRoller" %if (!IN_COMPLEX && FILT_COMPLEX) inBuff[%].re = *uptr++; inBuff[%].im = (real_T) 0.0; %else inBuff[%] = *uptr++; %endif %endroll %else %if (NUM_CHANS > 1) inBuff += % * %; %endif %endif %if (TREE == SYMMETRIC) { boolean_T tinBuff1 = 0; % *swap; int_T j, pIdx=0, iIdx=0, N=1;/* quiet bogus gcc warning */ %assign rollVars = ["/PhaseIdx", "/InIdx"] %roll sigIdx2 = [ 0:% ], lcv2 = 1, block, "Roller", rollVars int_T *phaseIdx = %; int_T *inIdx = %; int_T numSamps2 = numSamps >> 1; /* integer divide by 2 */ % *iBuff = inBuff; % *oBuff = lpBuff; /* Process N pairs of filters for this level */ for (j=0; j < N; j++) { int_T *memIdx = %; % *cffPtr = %; int_T mIdx = *memIdx; % *in = iBuff; % *sum = sums++; % *y0; int_T i; int_T oframe = numSamps >> 1; /* integer divide by 2 */ pIdx = *phaseIdx; iIdx = *inIdx; /* Highpass filter*/ %if (NUM_LEVELS > 1) if (% == %) { %else { %endif oBuff = out; out += (numSamps >> 1); /* integer divide by 2 */ tinBuff1 = %; %if (NUM_LEVELS > 1) } else { tinBuff1 = 0; iIdx = 0; %endif } y0 = oBuff; /* Each channel uses the same filter phase but accesses * its own state memory and input. */ for (i=0; i < numSamps; i++) { /* The pointer to state memory is set dFactor samples past the * desired location. This is because the memory pointer is * pre-decremented in the convolution loops. */ % *start = mem0 + mIdx + 1; % *mem = start; %if (FILT_COMPLEX) sum->re += CMULT_RE(*in, *cffPtr); sum->im += CMULT_IM(*in, *cffPtr); ++cffPtr; /* Perform the convolution for this phase (on every dFactor samples) * until we reach the start of the (linear) state memory */ while ((mem-=2) >= mem0) { sum->re += CMULT_RE(*mem, *cffPtr); sum->im += CMULT_IM(*mem, *cffPtr); cffPtr++; } /* wrap the state memory pointer to the next element */ mem += %; /* Finish the convolution for this phase */ while ((mem-=2) >= start) { sum->re += CMULT_RE(*mem, *cffPtr); sum->im += CMULT_IM(*mem, *cffPtr); cffPtr++; } %elseif (IN_COMPLEX) sum->re += in->re * (*cffPtr ); sum->im += in->im * (*cffPtr++); /* Perform the convolution for this phase (on every dFactor samples) * until we reach the start of the (linear) state memory */ while ((mem-=2) >= mem0) { sum->re += mem->re * (*cffPtr ); sum->im += mem->im * (*cffPtr++); } /* wrap the state memory pointer to the next element */ mem += %; /* Finish the convolution for this phase */ while ((mem-=2) >= start) { sum->re += mem->re * (*cffPtr ); sum->im += mem->im * (*cffPtr++); } %else *sum += *in * (*cffPtr++); /* Perform the convolution for this phase (on every dFactor samples) * until we reach the start of the (linear) state memory */ while ((mem-=2) >= mem0) *sum += *mem * (*cffPtr++); /* wrap the state memory pointer to the next element */ mem += %; /* Finish the convolution for this phase */ while ((mem-=2) >= start) *sum += *mem * (*cffPtr++); %endif if (++pIdx == 2) { % *y = y0 + iIdx; if (tinBuff1) y += %; *y = *sum; %if (OUT_COMPLEX) sum->re = sum->im = 0.0; %else *sum = 0.0; %endif if (++iIdx == oframe) { iIdx = 0; tinBuff1 = !tinBuff1; } pIdx = 0; cffPtr = cffHBase; } if (++mIdx == %) mIdx = 0; *(mem0+mIdx) = *in++; } /* frame */ if (iIdx == oframe) iIdx = 0; /*doFilter(S, iBuff, oBuff, (*sums)++, *mem0, numSamps, &pIdx, &mIdx, &iIdx, &cffRPtr, &cffIPtr, hpOrder, mxGetPr(HFILT_ARG), mxGetPi(HFILT_ARG), &tinBuff1);*/ *(&% + filtIdx++) = cffPtr; if (% == %) *(memIdx) = mIdx; mem0 += %; /* Lowpass Filter accesses the same inputs and has the same phase */ memIdx = %; pIdx = *phaseIdx; iIdx = *inIdx; mIdx = *(memIdx); cffPtr = %; %if (NUM_LEVELS > 1) if (% == %) { %else { %endif oBuff = out; out += numSamps2; tinBuff1 = %; %if (NUM_LEVELS > 1) } else { oBuff += numSamps2; tinBuff1 = 0; iIdx = 0; %endif } in = iBuff; y0 = oBuff; sum = sums++; for (i=0; i < numSamps; i++) { % *start = mem0 + mIdx + 1; % *mem = start; %if (FILT_COMPLEX) sum->re += CMULT_RE(*in, *cffPtr); sum->im += CMULT_IM(*in, *cffPtr); ++cffPtr; while ((mem-=2) >= mem0) { sum->re += CMULT_RE(*mem, *cffPtr); sum->im += CMULT_IM(*mem, *cffPtr); cffPtr++; } mem += %; while ((mem-=2) >= start) { sum->re += CMULT_RE(*mem, *cffPtr); sum->im += CMULT_IM(*mem, *cffPtr); cffPtr++; } %elseif (IN_COMPLEX) sum->re += in->re * (*cffPtr ); sum->im += in->im * (*cffPtr++); while ((mem-=2) >= mem0) { sum->re += mem->re * (*cffPtr ); sum->im += mem->im * (*cffPtr++); } mem += %; while ((mem-=2) >= start) { sum->re += mem->re * (*cffPtr ); sum->im += mem->im * (*cffPtr++); } %else *sum += *in * *cffPtr++; while ((mem-=2) >= mem0) *sum += *mem * (*cffPtr++); mem += %; while ((mem-=2) >= start) *sum += *mem * (*cffPtr++); %endif if (++pIdx == 2) { % *y = y0 + iIdx; if (tinBuff1) y += %; *y = *sum; %if (OUT_COMPLEX) sum->re = 0.0; sum->im = 0.0; %else *sum = 0.0; %endif if (++iIdx == oframe) { iIdx = 0; tinBuff1 = !tinBuff1; } pIdx = 0; cffPtr = cffLBase; } if (++mIdx == %) mIdx = 0; *(mem0+mIdx) = *in++; } /* frame */ if (iIdx == oframe) iIdx = 0; /*doFilter(S, iBuff, oBuff, (*sums)++, *mem0, numSamps, &pIdx, &mIdx, &iIdx, &cffRPtr, &cffIPtr, lpOrder, mxGetPr(LFILT_ARG), mxGetPi(LFILT_ARG), &tinBuff1);*/ *(&% + filtIdx++) = cffPtr; if (% == %) *(memIdx) = mIdx; mem0 += %; iBuff += numSamps; oBuff += numSamps2; } %if (NUM_CHANS > 1) if (% == %) { %endif *phaseIdx = pIdx; *inIdx = iIdx; %if (NUM_CHANS > 1) } %endif N *= 2; numSamps = numSamps2; swap = inBuff; inBuff = lpBuff; lpBuff = swap; %endroll %% LEVELS /* Switch output buffers here */ %if (NUM_CHANS > 1) if (% == %) { %endif % = !(%); %if (NUM_CHANS > 1) } %endif } %else %% ASYMMETRIC { int_T pwIdx = 0; boolean_T *wrBuff1 = %; %roll sigIdx2 = [ 0:% ], lcv2 = 1, block, "InlineRoller" int_T pIdx = %; int_T iIdx = %; int_T mIdx = %; % *cffPtr = %; boolean_T tinBuff1 = *wrBuff1; % *in = inBuff; % *y0 = out; % *sum = sums++; % *lpout; boolean_T sBuff1; int_T oframe = numSamps >> 1; /* integer divide by 2 */ int_T i; /* Each channel uses the same filter phase but accesses * its own state memory and input. */ for (i=0; i < numSamps; i++) { /* The pointer to state memory is set dFactor samples past the * desired location. This is because the memory pointer is * pre-decremented in the convolution loops. */ % *start = mem0 + mIdx + 1; % *mem = start; %if (FILT_COMPLEX) sum->re += CMULT_RE(*in, *cffPtr); sum->im += CMULT_IM(*in, *cffPtr); cffPtr++; /* Perform the convolution for this phase (on every dFactor samples) * until we reach the start of the (linear) state memory */ while ((mem-=2) >= mem0) { sum->re += CMULT_RE(*mem, *cffPtr); sum->im += CMULT_IM(*mem, *cffPtr); cffPtr++; } /* wrap the state memory pointer to the next element */ mem += %; /* Finish the convolution for this phase */ while ((mem-=2) >= start) { sum->re += CMULT_RE(*mem, *cffPtr); sum->im += CMULT_IM(*mem, *cffPtr); cffPtr++; } %elseif (IN_COMPLEX) sum->re += in->re * (*cffPtr ); sum->im += in->im * (*cffPtr++); /* Perform the convolution for this phase (on every dFactor samples) * until we reach the start of the (linear) state memory */ while ((mem-=2) >= mem0) { sum->re += mem->re * (*cffPtr ); sum->im += mem->im * (*cffPtr++); } /* wrap the state memory pointer to the next element */ mem += %; /* Finish the convolution for this phase */ while ((mem-=2) >= start) { sum->re += mem->re * (*cffPtr ); sum->im += mem->im * (*cffPtr++); } %else *sum += *in * (*cffPtr++); /* Perform the convolution for this phase (on every dFactor samples) * until we reach the start of the (linear) state memory */ while ((mem-=2) >= mem0) *sum += *mem * (*cffPtr++); /* wrap the state memory pointer to the next element */ mem += %; /* Finish the convolution for this phase */ while ((mem-=2) >= start) *sum += *mem * (*cffPtr++); %endif if (++pIdx == 2) { % *y = y0 + iIdx; if (tinBuff1) y += %; *y = *sum; %if (OUT_COMPLEX) sum->re = 0.0; sum->im = 0.0; %else *sum = 0.0; %endif if (++iIdx == oframe) { iIdx = 0; tinBuff1 = !tinBuff1; } pIdx = 0; cffPtr = cffHBase; } if (++mIdx == %) mIdx = 0; *(mem0+mIdx) = *in++; } /* frame */ if (iIdx == oframe) iIdx = 0; sBuff1 = tinBuff1; %if (NUM_CHANS > 1) if (% == %) { %endif % = mIdx; %if (NUM_CHANS > 1) } %endif %= cffPtr; mem0 += %; pIdx = %; iIdx = %; mIdx = %; cffPtr = %; if (% == %) { out += (numSamps >> 1); /* integer divide by 2 */ tinBuff1 = *wrBuff1; lpout = out; } else { tinBuff1 = 0; lpout = lpBuff; } in = inBuff; y0 = lpout; sum = sums++; for (i=0; i < numSamps; i++) { % *start = mem0 + mIdx + 1; % *mem = start; %if (FILT_COMPLEX) sum->re += CMULT_RE(*in, *cffPtr); sum->im += CMULT_IM(*in, *cffPtr); ++cffPtr; while ((mem-=2) >= mem0) { sum->re += CMULT_RE(*mem, *cffPtr); sum->im += CMULT_IM(*mem, *cffPtr); cffPtr++; } mem += %; while ((mem-=2) >= start) { sum->re += CMULT_RE(*mem, *cffPtr); sum->im += CMULT_IM(*mem, *cffPtr); cffPtr++; } %elseif (IN_COMPLEX) sum->re += in->re * (*cffPtr ); sum->im += in->im * (*cffPtr++); while ((mem-=2) >= mem0) { sum->re += mem->re * (*cffPtr ); sum->im += mem->im * (*cffPtr++); } mem += %; while ((mem-=2) >= start) { sum->re += mem->re * (*cffPtr ); sum->im += mem->im * (*cffPtr++); } %else *sum += *in * (*cffPtr++); while ((mem-=2) >= mem0) *sum += *mem * (*cffPtr++); mem += %; while ((mem-=2) >= start) *sum += *mem * (*cffPtr++); %endif if (++pIdx == 2) { % *y = y0 + iIdx; if (tinBuff1) y += %; *y = *sum; %if (OUT_COMPLEX) sum->re = 0.0; sum->im = 0.0; %else *sum = 0.0; %endif if (++iIdx == oframe) { iIdx = 0; tinBuff1 = !tinBuff1; } pIdx = 0; cffPtr = cffLBase; } if (++mIdx == %) mIdx = 0; *(mem0+mIdx) = *in++; } /* frame */ if (iIdx == oframe) iIdx = 0; %if (NUM_CHANS > 1) if (% == %) { %endif /* Update the counters and the output buffer selector */ % = pIdx; % = iIdx; % = mIdx; *wrBuff1 = sBuff1; %if (NUM_CHANS > 1) } %endif /* Next input frame is the output of the lowpass filter */ *(&% + filtIdx++) = cffPtr; inBuff = lpBuff; if (lpBuff == lpBuff0) { lpBuff = lpBuff0 + %; } else { lpBuff = lpBuff0; } pwIdx++; wrBuff1++; mem0 += %; numSamps >>= 1; /* integer divide by 2 */ out += numSamps; %endroll %% LEVELS } %endif %% SYMMETRIC %endroll %% CHANNELS } %if !LibIsSFcnSingleRate(block) } /* Sample Hit */ %endif } %endfunction %% UpdateCode %% Function: OutputsCode ========================================================== %% %function OutputsCode(block, system) Output { /* % Block: % (%) */ %assign astr = "" %foreach II = NumDataOutputPorts-1 %assign astr = astr + "%, " %endforeach %% %if (TREE == ASYMMETRIC) /* The iterative filtering routine has the outputs grouped by channel */ %if (SAMPLE_BASED) /* Output ports have width=numChans but different sample times */ %assign FRAME = 1 %foreach II = NUM_LEVELS-1 %assign FRAME = FRAME * 2 %endforeach %assign CHAN_SIZE = 2 * FRAME % *outPorts[%] = { % % }; int_T *outIdx = %; int_T offset = 0; int_T frame = %; %% %if !LibIsSFcnSingleRate(block) %assign initStr = "" %foreach idx = SIZE(OutputPortTIDs,1) %% Get global TID for each output port: %assign initStr = initStr + "%" + ... "%<(idx+1) == SIZE(OutputPortTIDs,1) ? "": ", ">" + ... "%<(idx+1) % 20 == 0? STRING("\n"): "">" %endforeach static const int_T tids[%] = {%}; %endif %roll sigIdx1 = [ 0:% ], lcv1 = 1, block, "InlineRoller" %if !LibIsSFcnSingleRate(block) %assign tidstr = "tids[%]" %% tidstr is the GLOBAL TID, so use LibIsSampleHit, not LibIsSFcnSampleHit: if (%) { %endif % *yout = outPorts[%]; % *y = % + offset + *outIdx; if (*outIdx >= frame) y += % - frame; %roll sigIdx2 = [ 0:% ], lcv2 = 3, block, "InlineRoller" *yout++ = *y; y += %; %endroll if (++(*outIdx) == 2*frame) *outIdx = 0; %if !LibIsSFcnSingleRate(block) } %endif ++outIdx; offset += frame; if (% < %) frame /= 2; %endroll %else /* Output ports have the same sample time but different widths */ %assign FRAME = LibDataOutputPortWidth(0) / NUM_CHANS %if !LibIsSFcnSingleRate(block) if (%) { %endif %% % *outPorts[%] = { % % }; int_T *outIdx = %; int_T offset = 0; int_T outPortWidth = %; %% %assign CHAN_SIZE = 2 * FRAME %roll sigIdx1 = [ 0:% ], lcv1 = 1, block, "InlineRoller" % *yout = outPorts[%]; % *y = % + offset; int_T i; if (*outIdx > 0) y += %; %roll sigIdx2 = [ 0:% ], lcv2 = 1, block, "InlineRoller" for (i=0; i < outPortWidth; i++) *yout++ = *(y + i); y += %; %endroll if (*outIdx > 0) *outIdx = 0; else *outIdx = 1; outIdx++; offset += outPortWidth; if (% < %) { outPortWidth >>= 1; /* integer divide by 2 */ } %endroll %if !LibIsSFcnSingleRate(block) } %endif %endif %% SAMPLE_BASED %else /* Symmetric Tree: all output ports have same sample time and same width. * The iterative filtering routine has the outputs grouped by channel. */ %assign FRAME = LibDataOutputPortWidth(0) / NUM_CHANS %assign CHAN_SIZE = NumDataOutputPorts * FRAME %if !LibIsSFcnSingleRate(block) if (%) { %endif % *outPorts[%] = { % % }; int_T *outIdx = %; int_T offset = 0; %roll sigIdx1 = [ 0:% ], lcv1 = 1, block, "InlineRoller" % *yout = outPorts[%]; % *y = % + offset; if (*outIdx > 0) y += %; %roll sigIdx2 = [ 0:% ], lcv2 = 1, block, "InlineRoller" %if (SAMPLE_BASED) *yout++ = *y; y += %; %else %roll sigIdx3 = [ 0:% ], lcv3 = 1, block, "InlineRoller" *yout++ = *y++; %endroll y += %; %endif %endroll offset += %; %endroll if (*outIdx > 0) *outIdx = 0; else *outIdx = 1; %if !LibIsSFcnSingleRate(block) } %endif %endif } %endfunction %% OutputsCode %% [EOF] sdspadyad.tlc