A General Program to Perform Sampling Rate Conversion of Data by Rational Ratios

Return to Main Software Page

C
C-----------------------------------------------------------------------
C MAIN PROGRAM: TEST PROGRAM TO PERFORM SAMPLING RATE CONVERSION
C               BY A RATIONAL RATIO
C AUTHOR:       R E CROCHIERE
C               BELL LABORATORIES, MURRAY HILL, NEW JERSEY 07974
C INPUT:        COEF=ARRAY OF COEFFICIENTS FOR FIR INTERPOLATING FILTER
C-----------------------------------------------------------------------
C
      COMMON /SRCOM/ IQ, JQ, IL
      DIMENSION COEF(60), COFS(120), QBUF(30), ICTR(16), BUFL(24),
     *    BUFM(15)
      IQ = 0
      JQ = 0
      IL = 0
C
C THIS PROGRAM CONVERTS THE SAMPLING RATE OF A SIGNAL BY A RATIO OF L/M
C THE PROGRAM CALLS SRINIT TO INITIALIZE AND THEN CALLS SRCONV SUPPLYING
C INPUT DATA THROUGH BUFM AND TAKING OUTPUT DATA FROM BUFL
C
C INPUT: COEFFICIENTS ARE READ FROM THE STANDARD INPUT UNIT (IND)
C
C OUTPUT: ALL OUTPUT IS WRITTEN ON THE STANDARD OUTPUT UNIT (LPT)
C
      IND = I1MACH(1)
      LPT = I1MACH(2)
      NN = 60
      READ (IND,9999) (COEF(K),K=1,NN)
      WRITE (LPT,9998)
      WRITE (LPT,9997) (COEF(K),K=1,NN)
      WRITE (LPT,9996)
C
C INITIALIZE CONVERSION ROUTINE
C
      N = 119
      NC = 120
      NI = 16
      L = 8
      M = 5
      NQ = 30
      CALL SRINIT(M, L, QBUF, NQ, COEF, N, COFS, NC, ICTR, NI, IERR)
      WRITE (LPT,9995) IERR
      WRITE (LPT,9996)
C
C GENERATE UNIT SAMPLE
C
      DO 10 I=1,15
        BUFM(I) = 0.
  10  CONTINUE
      BUFM(1) = 1.
C
C PROCESS DATA
C
      ND = 3
      CALL SRCONV(BUFM, BUFL, ND, QBUF, COFS, ICTR)
      WRITE (LPT,9994)
      NN = 24
      WRITE (LPT,9997) (BUFL(K),K=1,NN)
9999  FORMAT (7F11.0)
9998  FORMAT (13H COEFFICIENTS)
9997  FORMAT (1X, 5F10.6)
9996  FORMAT (1H )
9995  FORMAT (6H IERR=, I3)
9994  FORMAT (21H UNIT SAMPLE RESPONSE)
      STOP
      END
C
C-----------------------------------------------------------------------
C SUBROUTINE: SRINIT
C INITIALIZATION FOR SRCONV WHICH CONVERTS THE SAMPLING RATE
C OF A SIGNAL BY THE RATIO OF L/M
C-----------------------------------------------------------------------
C
      SUBROUTINE SRINIT(M, L, QBUF, NQ, COEF, N, COFS, NC, ICTR, NI,
     *    IERR)
      COMMON /SRCOM/ IQ, JQ, IL
      DIMENSION QBUF(1), COEF(1), COFS(1), ICTR(1)
C
C    M = DECIMATION RATIO
C    L = INTERPOLATION RATIO
C QBUF = STATE VARIABLE BUFFER
C   NQ = SIZE OF QBUF, GREATER OR EQUAL TO 2*(THE NEXT
C        GREATEST INTEGER OF N/L)
C COEF = ARRAY OF COEFFICIENTS FOR FIR INTERPOLATING FILTER
C    N = NO. OF TAPS IN THE FIR INTERPOLATING FILTER
C COFS = SCRAMBLED COEFFICIENT VECTOR GENERATED BY SRINIT
C   NC = SIZE OF COFS VECTOR, EQUAL TO OR GREATER THAN
C        L*(THE NEXT GREATEST INTEGER OF N/L)
C ICTR = CONTROL ARRAY GENERATED BY SRINIT AND USED BY SRCONV
C   NI = SIZE OF ICTR VECTOR EQUAL OR GREATER THAN 2*L
C IERR = ERROR CODE FOR DEBUGGING
C      = 0  NO ERRORS FOUND IN INITIALIZATION
C      = 1  QBUF (NQ) TOO SMALL
C      = 2  COFS (NC) TOO SMALL
C      = 3  ICTR (NI) TOO SMALL
C
      IERR = 0
      IL = L
C
C COMPUTE IQ
C
      IQ = N/L
      IF (N.NE.(IQ*L)) IQ = IQ + 1
      NP = IQ*L
      IF (NQ.LT.(2*IQ)) IERR = 1
      IF (NC.LT.NP) IERR = 2
      NCF = (N+1)/2
      FL = L
C
C ZERO OUT QBUF
C
      DO 10 I=1,NQ
        QBUF(I) = 0
  10  CONTINUE
C
C SCRAMBLE COEFFICIENTS
C
      I = 1
      DO 30 ML=1,L
        DO 20 MQ=1,IQ
          MX = (ML-1) + (MQ-1)*L
          IF (MX.LT.NCF) MM = NCF - MX
          IF (MX.GE.NCF) MM = MX - (N-NCF-1)
          IF (MM.LE.NCF) COFS(I) = COEF(MM)*FL
          IF (MM.GT.NCF) COFS(I) = 0.
          I = I + 1
  20    CONTINUE
  30  CONTINUE
C
C SETUP OF MOVING ADDRESS POINTER
C
      JQ = IQ
C
C GENERATE CONTROL ARRAY ICTR
C
      LM = L*M
      IF (NI.LT.(2*L)) IERR = 3
      LC = 0
      MC = 0
      INCR = 0
      K = 1
      DO 50 I=1,LM
        IF (LC.EQ.0) INCR = INCR + 1
        IF (MC.LT.(M-1)) GO TO 40
C
C NO OF SAMPLES TO UPDATE QBUF
C
        ICTR(K) = INCR
        INCR = 0
        K = K + 1
C
C STARTING LOCATION IN COFS VECTOR
C
        ICTR(K) = LC*IQ
        INCR = 0
        MC = -1
        K = K + 1
  40    LC = LC + 1
        IF (LC.GE.L) LC = 0
        MC = MC + 1
  50  CONTINUE
      RETURN
      END
C
C-----------------------------------------------------------------------
C SUBROUTINE: SRCONV
C CONVERTS THE SAMPLING RATE OF A SIGNAL BY THE RATIO L/M.
C SRINIT MUST BE CALLED PRIOR TO CALLING THIS ROUTINE.
C-----------------------------------------------------------------------
C
      SUBROUTINE SRCONV(BUFM, BUFL, ND, QBUF, COFS, ICTR)
      COMMON /SRCOM/ IQ, JQ, IL
      DIMENSION BUFM(1), BUFL(1), QBUF(1), COFS(1), ICTR(1)
C
C BUFM = INPUT DATA BUFFER OF SIZE ND*M
C BUFL = OUTPUT DATA BUFFER OF SIZE ND*L
C   ND = ANY POSITIVE INTEGER
C QBUF = STATE VARIABLE BUFFER
C COFS = SCRAMBLED COEFFICIENT VECTOR GENERATED BY SRINIT
C ICTR = CONTROL ARRAY GENERATED BY SRINIT AND USED BY SRCONV
C
      MB = 1
      LB = 1
      L = IL
      DO 50 I=1,ND
C
C MB = INDEX ON BUFM
C COMPUTE L OUTPUT SAMPLES
C
        K = 1
        DO 40 J=1,L
          JD = ICTR(K)
          IC = ICTR(K+1)
          K = K + 2
C
C UPDATE QBUF
C
  10      IF (JD.EQ.0) GO TO 20
          QBUF(JQ) = BUFM(MB)
          JQ1 = JQ + IQ
          QBUF(JQ1) = BUFM(MB)
          MB = MB + 1
          JQ = JQ - 1
          IF (JQ.EQ.0) JQ = IQ
          JD = JD - 1
          GO TO 10
C
C COMPUTE 1 SAMPLE OF OUTPUT DATA AND STORE IN BUFL
C
  20      SUM = 0.
          DO 30 KQ=1,IQ
            ICOF = KQ + IC
            IQB = KQ + JQ
            SUM = SUM + QBUF(IQB)*COFS(ICOF)
  30      CONTINUE
          BUFL(LB) = SUM
          LB = LB + 1
  40    CONTINUE
  50  CONTINUE
      RETURN
      END
Return to Main Software Page