📄 sunbuff.c
字号:
/*
* SUNBUFF A SIMULINK unbuffer block with overlap
*
* Syntax: [sys, x0] = sunbuff(t,x,u,flag,BufferOverlap,OutputIndex,sampleTime)
*
* Rick Spada Jan 28, 1994
* Gary Levenson July 24, 1994 - modified to include overlap
*
* Copyright (c) 1994-96 by The MathWorks, Inc.
* All Rights Reserved
* $Revision: 1.1 $ $Date: 1996/04/01 19:05:53 $
*/
#define S_FUNCTION_NAME sunbuff
#ifdef MATLAB_MEX_FILE
#include <stdio.h> /* needed for declaration of sprintf */
#include "mex.h" /* needed for declaration of mexErrMsgTxt */
#endif
/*
* need to include simstruc.h for the definition of the SimStruct and
* its associated macro definitions.
*/
#include "simstruc.h"
/*
* Defines for easy access of the input parameters
*/
#define NUM_ARGS 3
#define BUFFER_OVERLAP ssGetArg(S,0)
#define OUTPUT_INDEX ssGetArg(S,1)
#define SAMPLE_TIME ssGetArg(S,2)
/*
* mdlInitializeSizes - called to initialize the sizes array stored in
* the SimStruct. The sizes array defines the
* characteristics (number of inputs, outputs,
* states, etc.) of the S-Function.
*/
static void mdlInitializeSizes(S)
SimStruct *S;
{
/*
* Set-up size information.
*/
if (ssGetNumArgs(S) == NUM_ARGS) {
if ((mxGetN(SAMPLE_TIME)*mxGetM(SAMPLE_TIME) != 1) &&
(mxGetN(SAMPLE_TIME)*mxGetM(SAMPLE_TIME) != 2)) {
#ifdef MATLAB_MEX_FILE
mexErrMsgTxt("The sample time must be a scalar or a vector of length 2");
#endif
}
if ((mxGetN(BUFFER_OVERLAP) != 1) || (mxGetM(BUFFER_OVERLAP) != 1)) {
#ifdef MATLAB_MEX_FILE
mexErrMsgTxt("The buffer overlap must be a scalar");
#endif
}
ssSetNumContStates( S, 0);
ssSetNumDiscStates( S, 0);
ssSetNumInputs( S, -1);
ssSetNumOutputs( S, 1);
ssSetDirectFeedThrough(S, 0);
ssSetNumInputArgs( S, 3);
ssSetNumSampleTimes( S, 1);
ssSetNumRWork( S, -1);
ssSetNumIWork( S, 2);
ssSetNumPWork( S, 0);
} else {
#ifdef MATLAB_MEX_FILE
char err_msg[256];
sprintf(err_msg, "Wrong number of input arguments passed to S-function MEX-file.\n"
"%d input arguments were passed in when expecting %d input arguments.\n", ssGetNumArgs(S) + 4, NUM_ARGS + 4);
mexErrMsgTxt(err_msg);
#endif
}
}
/*
* mdlInitializeSampleTimes - initializes the array of sample times stored in
* the SimStruct associated with this S-Function.
*/
static void mdlInitializeSampleTimes(S)
SimStruct *S;
{
double sampleTime, offsetTime;
/*
* Note, blocks that are continuous in nature should have a single
* sample time of 0.0.
*/
sampleTime = mxGetPr(SAMPLE_TIME)[0];
if ((mxGetN(SAMPLE_TIME) * mxGetM(SAMPLE_TIME)) == 2)
offsetTime = mxGetPr(SAMPLE_TIME)[1];
else
offsetTime = 0.;
ssSetSampleTimeEvent(S, 0, sampleTime);
ssSetOffsetTimeEvent(S, 0, offsetTime);
}
/*
* mdlInitializeConditions - initializes the states for the S-Function
*/
static void mdlInitializeConditions(x0, S)
double *x0;
SimStruct *S;
{
double *buffer = ssGetRWork(S);
int *bufIndex = ssGetIWork(S);
int *bufOutputIndex = ssGetIWork(S)+ 1;
int i, bufSize, bufOverlap;
/*
* Initialize the buffer to all zeros, we could allow this to
* be an additional paramter.
*/
bufSize = ssGetNumInputs(S);
for (i = 0; i < bufSize; i++)
*buffer++ = 0.;
/*
* Initialize the current buffer position, buffer start, and output index
*/
bufOverlap = mxGetPr(BUFFER_OVERLAP)[0];
*bufOutputIndex = mxGetPr(OUTPUT_INDEX)[0];
*bufIndex = 0;
/*
* Some defensive programing
*/
if (ssGetNumInputs(S) != -1) {
if ((*bufOutputIndex) < 0) {
#ifdef MATLAB_MEX_FILE
char err_msg[256];
sprintf(err_msg,"Invalid Output Index specfied.\n"
"Output Index must be a positive integer\n");
mexErrMsgTxt(err_msg);
#endif
}
else if ( bufOverlap < 0 ) {
#ifdef MATLAB_MEX_FILE
mexErrMsgTxt("Invalid Overlap specfied - Overlap should be a positive integer\n");
#endif
}
else if ((*bufOutputIndex) > (bufSize - bufOverlap) ) {
#ifdef MATLAB_MEX_FILE
mexErrMsgTxt("Error: Output Index exceeds buffer frame \n");
#endif
}
}
}
/*
* mdlOutputs - computes the outputs of the S-Function
*/
static void mdlOutputs(y, x, u, S, tid)
double *y, *x, *u;
SimStruct *S;
int tid;
{
if (ssIsSampleHitEvent(S, 0, 0)) {
double *buffer = ssGetRWork(S);
int *bufIndex = ssGetIWork(S);
int *bufOutputIndex = ssGetIWork(S) + 1;
int bufSize = ssGetNumInputs(S);
int bufOverlap = mxGetPr(BUFFER_OVERLAP)[0];
/*
* bufIndex being zero is our queue to reload the buffer
*/
if ((*bufIndex) == 0) {
int i;
/*
* acquire the buffer data
*/
buffer = ssGetRWork(S);
for (i = 0; i < bufSize; i++) {
*buffer++ = *u++;
*bufIndex %= bufSize;
}
}
/*
* now output the overlap frame when the buffer is full
*/
buffer = ssGetRWork(S) + (*bufOutputIndex)++;
*y = *buffer;
if (++(*bufIndex) == bufSize - bufOverlap) {
*bufIndex = 0;
*bufOutputIndex = mxGetPr(OUTPUT_INDEX)[0];
}
}
}
/*
* mdlUpdate - computes the discrete states of the S-Function
*/
static void mdlUpdate(x, u, S, tid)
double *x, *u;
SimStruct *S;
int tid;
{
}
/*
* mdlDerivatives - computes the derivatives of the S-Function
*/
static void mdlDerivatives(dx, x, u, S, tid)
double *dx, *x, *u;
SimStruct *S;
int tid;
{
}
/*
* mdlTerminate - called at termination of model execution.
*/
static void mdlTerminate(S)
SimStruct *S;
{
}
#ifdef MATLAB_MEX_FILE /* Is this file being compiled as a MEX-file? */
#include "simulink.c" /* MEX-File interface mechanism */
#else
#include "cg_sfun.h" /* Code generation registration function */
#endif
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -