⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 sunbuff.c

📁 Proakis《contemporarycommunication systems using matlab》matlab源代码
💻 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 + -