fortran66のブログ

fortran について書きます。

MPEG1用 MPEG定数 & Subband filter

チラシ裏の下書きメモ帖です。テストしてません。

■ソース・コード

配列生成子のところで、[CHARACTER(LEN=nn):: ....]と明示的に指定することで、中のデータが自動的にその長さに調節されます。Fortran95までは、宣言長にそろえて空白を入れておかないと駄目だったので、便利になりました。

MODULE m_mpeg
   IMPLICIT NONE
   PUBLIC
   TYPE:: mpeg_parameters
    INTEGER:: mtype
    INTEGER:: layer
    INTEGER:: bit_rate
    INTEGER:: sample_rate
    INTEGER:: psychoacoustic
    INTEGER:: emphasis
    INTEGER:: padding
    INTEGER:: crc
    INTEGER:: mode
    INTEGER:: extension
    INTEGER:: mode_extension
    INTEGER:: copyright
    INTEGER:: original
   END TYPE mpeg_parameters
   !MPEG1 / audio
   INTEGER, PARAMETER:: mpeg_frame_size(0:2)    = [1152, 1152, 384]
   INTEGER, PARAMETER:: mpeg_sample_rates(0:3)  = [44100, 48000, 32000, 0]
   INTEGER, PARAMETER:: mpeg_bit_rates(0:14, 0:2) = &
        [[0, 32, 40, 48,  56,  64,  80,  96, 112, 128, 160, 192, 224, 256, 320], &
         [0, 32, 48, 56,  64,  80,  96, 112, 128, 160, 192, 224, 256, 320, 384], &
         [0, 32, 64, 96, 128, 160, 192, 224, 256, 288, 320, 352, 384, 414, 448]]  
   CHARACTER(LEN = 8), PARAMETER:: mpeg_mode_names(0:3)    = [CHARACTER(LEN = 8):: 'stereo', 'j-stereo', 'dual-ch', 'mono']
   CHARACTER(LEN = 3), PARAMETER:: mpeg_layer_names(0:2)   = [CHARACTER(LEN = 3):: 'III', 'II', 'I']
   CHARACTER(LEN = 7), PARAMETER:: mpeg_version_names(0:3) = [CHARACTER(LEN = 7):: '', '', 'MPEG-II', 'MPEG-I']
   CHARACTER(LEN = 6), PARAMETER:: mpeg_psy_names(0:3)     = [CHARACTER(LEN = 6):: '',  '', '', '']
   CHARACTER(LEN = 7), PARAMETER:: mpeg_demp_names(0:3)    = [CHARACTER(LEN = 7):: 'none', '50/15us', '', 'CITT']
END MODULE m_mpeg

プロトタイプ・フィルターの定義のところで、一行が132文字を超えてしまっているので、Fortran規格外です。132はラインプリンタの桁数か?

MODULE m_polyphase
   USE m_kind
   IMPLICIT NONE
   PRIVATE
   TYPEPUBLIC :: t_subband
      REAL(kd), ALLOCATABLE :: subband(:, :, :)
    CONTAINS
      PROCEDURE :: init
      PROCEDURE :: polyphase_filter12
   END TYPE t_subband  
   
   INTEGER, PARAMETER :: nsize = 511, nband = 31
   REAL(kd), PARAMETER :: pi = 4 * ATAN(1.0_kd), pi64 = pi / 64
   REAL(kd), SAVE :: coeff(0:nband, 0:63)

   REAL(kd), PARAMETER :: prototype(0:nsize) = & ! ISO  Table C.1   ! non-standard   > 136 column 
[ 0.000000000_kd, -0.000000477_kd, -0.000000477_kd, -0.000000477_kd, -0.000000477_kd, -0.000000477_kd, -0.000000477_kd, -0.000000954_kd, & 
 -0.000000954_kd, -0.000000954_kd, -0.000000954_kd, -0.000001431_kd, -0.000001431_kd, -0.000001907_kd, -0.000001907_kd, -0.000002384_kd, & 
 -0.000002384_kd, -0.000002861_kd, -0.000003338_kd, -0.000003338_kd, -0.000003815_kd, -0.000004292_kd, -0.000004768_kd, -0.000005245_kd, & 
 -0.000006199_kd, -0.000006676_kd, -0.000007629_kd, -0.000008106_kd, -0.000009060_kd, -0.000010014_kd, -0.000011444_kd, -0.000012398_kd, & 
 -0.000013828_kd, -0.000014782_kd, -0.000016689_kd, -0.000018120_kd, -0.000019550_kd, -0.000021458_kd, -0.000023365_kd, -0.000025272_kd, & 
 -0.000027657_kd, -0.000030041_kd, -0.000032425_kd, -0.000034809_kd, -0.000037670_kd, -0.000040531_kd, -0.000043392_kd, -0.000046253_kd, & 
 -0.000049591_kd, -0.000052929_kd, -0.000055790_kd, -0.000059605_kd, -0.000062943_kd, -0.000066280_kd, -0.000070095_kd, -0.000073433_kd, & 
 -0.000076771_kd, -0.000080585_kd, -0.000083923_kd, -0.000087261_kd, -0.000090599_kd, -0.000093460_kd, -0.000096321_kd, -0.000099182_kd, & 
  0.000101566_kd,  0.000103951_kd,  0.000105858_kd,  0.000107288_kd,  0.000108242_kd,  0.000108719_kd,  0.000108719_kd,  0.000108242_kd, & 
  0.000106812_kd,  0.000105381_kd,  0.000102520_kd,  0.000099182_kd,  0.000095367_kd,  0.000090122_kd,  0.000084400_kd,  0.000077724_kd, & 
  0.000069618_kd,  0.000060558_kd,  0.000050545_kd,  0.000039577_kd,  0.000027180_kd,  0.000013828_kd, -0.000000954_kd, -0.000017166_kd, & 
 -0.000034332_kd, -0.000052929_kd, -0.000072956_kd, -0.000093937_kd, -0.000116348_kd, -0.000140190_kd, -0.000165462_kd, -0.000191212_kd, & 
 -0.000218868_kd, -0.000247478_kd, -0.000277042_kd, -0.000307560_kd, -0.000339031_kd, -0.000371456_kd, -0.000404358_kd, -0.000438213_kd, & 
 -0.000472546_kd, -0.000507355_kd, -0.000542164_kd, -0.000576973_kd, -0.000611782_kd, -0.000646591_kd, -0.000680923_kd, -0.000714302_kd, & 
 -0.000747204_kd, -0.000779152_kd, -0.000809669_kd, -0.000838757_kd, -0.000866413_kd, -0.000891685_kd, -0.000915051_kd, -0.000935555_kd, & 
 -0.000954151_kd, -0.000968933_kd, -0.000980854_kd, -0.000989437_kd, -0.000994205_kd, -0.000995159_kd, -0.000991821_kd, -0.000983715_kd, & 
  0.000971317_kd,  0.000953674_kd,  0.000930786_kd,  0.000902653_kd,  0.000868797_kd,  0.000829220_kd,  0.000783920_kd,  0.000731945_kd, & 
  0.000674248_kd,  0.000610352_kd,  0.000539303_kd,  0.000462532_kd,  0.000378609_kd,  0.000288486_kd,  0.000191689_kd,  0.000088215_kd, & 
 -0.000021458_kd, -0.000137329_kd, -0.000259876_kd, -0.000388145_kd, -0.000522137_kd, -0.000661850_kd, -0.000806808_kd, -0.000956535_kd, & 
 -0.001111031_kd, -0.001269817_kd, -0.001432419_kd, -0.001597881_kd, -0.001766682_kd, -0.001937389_kd, -0.002110004_kd, -0.002283096_kd, & 
 -0.002457142_kd, -0.002630711_kd, -0.002803326_kd, -0.002974033_kd, -0.003141880_kd, -0.003306866_kd, -0.003467083_kd, -0.003622532_kd, & 
 -0.003771782_kd, -0.003914356_kd, -0.004048824_kd, -0.004174709_kd, -0.004290581_kd, -0.004395962_kd, -0.004489899_kd, -0.004570484_kd, & 
 -0.004638195_kd, -0.004691124_kd, -0.004728317_kd, -0.004748821_kd, -0.004752159_kd, -0.004737377_kd, -0.004703045_kd, -0.004649162_kd, & 
 -0.004573822_kd, -0.004477024_kd, -0.004357815_kd, -0.004215240_kd, -0.004049301_kd, -0.003858566_kd, -0.003643036_kd, -0.003401756_kd, & 
  0.003134727_kd,  0.002841473_kd,  0.002521515_kd,  0.002174854_kd,  0.001800537_kd,  0.001399517_kd,  0.000971317_kd,  0.000515938_kd, & 
  0.000033379_kd, -0.000475883_kd, -0.001011848_kd, -0.001573563_kd, -0.002161503_kd, -0.002774239_kd, -0.003411293_kd, -0.004072189_kd, & 
 -0.004756451_kd, -0.005462170_kd, -0.006189346_kd, -0.006937027_kd, -0.007703304_kd, -0.008487225_kd, -0.009287834_kd, -0.010103703_kd, & 
 -0.010933399_kd, -0.011775017_kd, -0.012627602_kd, -0.013489246_kd, -0.014358521_kd, -0.015233517_kd, -0.016112804_kd, -0.016994476_kd, & 
 -0.017876148_kd, -0.018756866_kd, -0.019634247_kd, -0.020506859_kd, -0.021372318_kd, -0.022228718_kd, -0.023074150_kd, -0.023907185_kd, & 
 -0.024725437_kd, -0.025527000_kd, -0.026310921_kd, -0.027073860_kd, -0.027815342_kd, -0.028532982_kd, -0.029224873_kd, -0.029890060_kd, & 
 -0.030526638_kd, -0.031132698_kd, -0.031706810_kd, -0.032248020_kd, -0.032754898_kd, -0.033225536_kd, -0.033659935_kd, -0.034055710_kd, & 
 -0.034412861_kd, -0.034730434_kd, -0.035007000_kd, -0.035242081_kd, -0.035435200_kd, -0.035586357_kd, -0.035694122_kd, -0.035758972_kd, & 
  0.035780907_kd,  0.035758972_kd,  0.035694122_kd,  0.035586357_kd,  0.035435200_kd,  0.035242081_kd,  0.035007000_kd,  0.034730434_kd, & 
  0.034412861_kd,  0.034055710_kd,  0.033659935_kd,  0.033225536_kd,  0.032754898_kd,  0.032248020_kd,  0.031706810_kd,  0.031132698_kd, & 
  0.030526638_kd,  0.029890060_kd,  0.029224873_kd,  0.028532982_kd,  0.027815342_kd,  0.027073860_kd,  0.026310921_kd,  0.025527000_kd, & 
  0.024725437_kd,  0.023907185_kd,  0.023074150_kd,  0.022228718_kd,  0.021372318_kd,  0.020506859_kd,  0.019634247_kd,  0.018756866_kd, & 
  0.017876148_kd,  0.016994476_kd,  0.016112804_kd,  0.015233517_kd,  0.014358521_kd,  0.013489246_kd,  0.012627602_kd,  0.011775017_kd, & 
  0.010933399_kd,  0.010103703_kd,  0.009287834_kd,  0.008487225_kd,  0.007703304_kd,  0.006937027_kd,  0.006189346_kd,  0.005462170_kd, & 
  0.004756451_kd,  0.004072189_kd,  0.003411293_kd,  0.002774239_kd,  0.002161503_kd,  0.001573563_kd,  0.001011848_kd,  0.000475883_kd, & 
 -0.000033379_kd, -0.000515938_kd, -0.000971317_kd, -0.001399517_kd, -0.001800537_kd, -0.002174854_kd, -0.002521515_kd, -0.002841473_kd, & 
  0.003134727_kd,  0.003401756_kd,  0.003643036_kd,  0.003858566_kd,  0.004049301_kd,  0.004215240_kd,  0.004357815_kd,  0.004477024_kd, & 
  0.004573822_kd,  0.004649162_kd,  0.004703045_kd,  0.004737377_kd,  0.004752159_kd,  0.004748821_kd,  0.004728317_kd,  0.004691124_kd, & 
  0.004638195_kd,  0.004570484_kd,  0.004489899_kd,  0.004395962_kd,  0.004290581_kd,  0.004174709_kd,  0.004048824_kd,  0.003914356_kd, & 
  0.003771782_kd,  0.003622532_kd,  0.003467083_kd,  0.003306866_kd,  0.003141880_kd,  0.002974033_kd,  0.002803326_kd,  0.002630711_kd, & 
  0.002457142_kd,  0.002283096_kd,  0.002110004_kd,  0.001937389_kd,  0.001766682_kd,  0.001597881_kd,  0.001432419_kd,  0.001269817_kd, & 
  0.001111031_kd,  0.000956535_kd,  0.000806808_kd,  0.000661850_kd,  0.000522137_kd,  0.000388145_kd,  0.000259876_kd,  0.000137329_kd, & 
  0.000021458_kd, -0.000088215_kd, -0.000191689_kd, -0.000288486_kd, -0.000378609_kd, -0.000462532_kd, -0.000539303_kd, -0.000610352_kd, & 
 -0.000674248_kd, -0.000731945_kd, -0.000783920_kd, -0.000829220_kd, -0.000868797_kd, -0.000902653_kd, -0.000930786_kd, -0.000953674_kd, & 
  0.000971317_kd,  0.000983715_kd,  0.000991821_kd,  0.000995159_kd,  0.000994205_kd,  0.000989437_kd,  0.000980854_kd,  0.000968933_kd, & 
  0.000954151_kd,  0.000935555_kd,  0.000915051_kd,  0.000891685_kd,  0.000866413_kd,  0.000838757_kd,  0.000809669_kd,  0.000779152_kd, & 
  0.000747204_kd,  0.000714302_kd,  0.000680923_kd,  0.000646591_kd,  0.000611782_kd,  0.000576973_kd,  0.000542164_kd,  0.000507355_kd, & 
  0.000472546_kd,  0.000438213_kd,  0.000404358_kd,  0.000371456_kd,  0.000339031_kd,  0.000307560_kd,  0.000277042_kd,  0.000247478_kd, & 
  0.000218868_kd,  0.000191212_kd,  0.000165462_kd,  0.000140190_kd,  0.000116348_kd,  0.000093937_kd,  0.000072956_kd,  0.000052929_kd, & 
  0.000034332_kd,  0.000017166_kd,  0.000000954_kd, -0.000013828_kd, -0.000027180_kd, -0.000039577_kd, -0.000050545_kd, -0.000060558_kd, & 
 -0.000069618_kd, -0.000077724_kd, -0.000084400_kd, -0.000090122_kd, -0.000095367_kd, -0.000099182_kd, -0.000102520_kd, -0.000105381_kd, & 
 -0.000106812_kd, -0.000108242_kd, -0.000108719_kd, -0.000108719_kd, -0.000108242_kd, -0.000107288_kd, -0.000105858_kd, -0.000103951_kd, & 
  0.000101566_kd,  0.000099182_kd,  0.000096321_kd,  0.000093460_kd,  0.000090599_kd,  0.000087261_kd,  0.000083923_kd,  0.000080585_kd, & 
  0.000076771_kd,  0.000073433_kd,  0.000070095_kd,  0.000066280_kd,  0.000062943_kd,  0.000059605_kd,  0.000055790_kd,  0.000052929_kd, & 
  0.000049591_kd,  0.000046253_kd,  0.000043392_kd,  0.000040531_kd,  0.000037670_kd,  0.000034809_kd,  0.000032425_kd,  0.000030041_kd, & 
  0.000027657_kd,  0.000025272_kd,  0.000023365_kd,  0.000021458_kd,  0.000019550_kd,  0.000018120_kd,  0.000016689_kd,  0.000014782_kd, & 
  0.000013828_kd,  0.000012398_kd,  0.000011444_kd,  0.000010014_kd,  0.000009060_kd,  0.000008106_kd,  0.000007629_kd,  0.000006676_kd, & 
  0.000006199_kd,  0.000005245_kd,  0.000004768_kd,  0.000004292_kd,  0.000003815_kd,  0.000003338_kd,  0.000003338_kd,  0.000002861_kd, & 
  0.000002384_kd,  0.000002384_kd,  0.000001907_kd,  0.000001907_kd,  0.000001431_kd,  0.000001431_kd,  0.000000954_kd,  0.000000954_kd, & 
  0.000000954_kd,  0.000000954_kd,  0.000000477_kd,  0.000000477_kd,  0.000000477_kd,  0.000000477_kd,  0.000000477_kd,  0.000000477_kd  ]
 CONTAINS
  !----------------------------------------------------------------------
  SUBROUTINE init(this, channel)
     CLASS(t_subband), INTENT(OUT) :: this
     INTEGER, INTENT(IN) :: channel 
     INTEGER :: i, j
     
     ! alloc subband 
     ALLOCATE( this%subband(0:nband, 0:11, 0:channel) )
     
     ! make-coeff  ISO C.1.3 
     DO i = 0, 31
      DO j = 0, 63 ! rounding at 9th decimal
       coeff(i, j) = 1.0e-9_kd * ANINT( 1.0e9_kd * COS(MOD( (2 * i + 1) * (j - 16), 128) * pi64) )
      END DO
     END DO
 
     RETURN
  END SUBROUTINE init
  !----------------------------------------------------------------------
  SUBROUTINE polyphase_filter12(this, pcm)
     CLASS(t_subband), INTENT(OUT) :: this
     REAL(kd), INTENT(IN ) :: pcm(:, :)
     INTEGER :: i, ichannel, istart, iend

     DO i = 0, 11 ! ISO C.1.3 Analysis subband filter 
      iend   = 864 - 32 * i
      istart = iend - 512 + 1
      DO ichannel = 0, UBOUND(pcm, 2)
       CALL polyphase_filter( prototype * pcm(istart:iend, ichannel), this%subband(:, i, ichannel) )
      END DO
     END DO
 
     RETURN
   CONTAINS 
     !-------------------------------------
     SUBROUTINE polyphase_filter(z, s)
       REAL(kd), INTENT(IN ) :: z(0:)
       REAL(kd), INTENT(OUT) :: s(0:)
       REAL(kd) ::  y(0:63), f(0:31)
       INTEGER :: i
       
       FORALL(i = 0:63)
        y(i) = SUM(z(i:511:64)) 
       END FORALL
       s = MATMUL(coeff, y)
       
       RETURN
     END SUBROUTINE polyphase_filter
     !-------------------------------------
  END SUBROUTINE polyphase_filter12
  !----------------------------------------------------------------------
END MODULE m_polyphase