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

📄 ssynth.dsp

📁 作者:Analog Devices,Inc 平台:ADSP21xx 编程语言:ASM 说明:ADSP21xx用AD的16位定点DSP作音频压缩器性价比不错
💻 DSP
字号:
.module/boot=3/boot=4   lpc_sync_synth;

{ SSYNTH.DSP - synthesizes lpc speech on a pitch syncronious boundry.

  INPUT:
    i1  -> (negative) reflection coefficient (k[]'s) 
    l1  =  0
    i2  -> output (speech) buffer 
    l2  =  0
    ax1 =  pitch period
    mx1 =  gain

  OUTPUT:
    Ouput buffer filled

  FUNCTIONS CALLED:
    noise_rand     (random number generator)

  DESCRIPTION:
    clear_filter: clears delay line, initializes variables 
                  (no arguments required)

    synthesis   : updates the frame delay line  -> new -> old ->
      then synthesises a frame of speech, based on interpolated
      parameters (cur_) from the last frame (old_) and the latest (new_).
      When a frame is considered voiced the filter is excited with an 
      impuls on a pitchsyncronous boundry. When a frame is unvoiced, the
      filter is excited whith random noise. Before input to the filter
      the excitation is scaled to an appropriate value depending on
      voiced/unvoiced status and the gain. The lattice filter is
      taken from the apps handbook. 
                  
      In order to interpolate the parameter a DELAY OF ONE
      FRAME is introduced!
}

  { include constant definitions }
#include "lpc.h";

.entry synthesis, clear_filter;

.external noise_rand;

.var/pm/ram/circ e_back[N];   {delay line}
.var/dm/ram      lo_noise_seed,hi_noise_seed;
.var/pm/ram      new_k[N];
.var/dm/ram      new_gain;
.var/dm/ram      new_pitch;
.var/pm/ram      old_k[N];
.var/dm/ram      old_gain;
.var/dm/ram      old_pitch;
.var/dm/ram/circ cur_k[N];
.var/dm/ram      cur_gain;
.var/dm/ram      cur_pitch;
.var/dm/ram      pif_cnt;  {Place In Frame - cntr}
.var/dm/ram      pp_cnt;   {pitch period - cntr}
.var/dm/ram      first_time;

  {clear filter and return}
clear_filter:
  
   {clear the filter}
  i4 = ^e_back;  l4 = 0;
  ar = 0;
  cntr = N;
  do clear_loop until ce;
  clear_loop: pm(i4,m5) = ar;      

  {initialize seed value for random nr generation}
  ax0 = 0;
  dm(lo_noise_seed) = ax0;
  dm(hi_noise_seed) = ax0;

  ax0 = 1;
  dm(first_time) = ax0; {first_time = TRUE}
  
rts;
  
  {generate one frame of data and output to speech buffer}

synthesis:
  ax0 = dm(first_time);
  ar  = pass ax0;
  if eq jump not_first;
    {copy parm's to new}     {first_time = TRUE}
    dm(new_pitch) = ax1;
    dm(new_gain)  = mx1;
    i6 = ^new_k;  l6 = 0;
    cntr = N;
    do move_to_new until ce;
      ax0 = dm(i1,m1);
    move_to_new: pm(i6,m5) = ax0;

    {start of by interpolating}
    ax0 = 1;
    dm(pp_cnt) = ax0;

     {don't do this anymore}   
    ax0 = 0;
    dm(first_time) = ax0;
    jump done;
  not_first:                 {first_time = FALSE}
     {move parm's from old to new and update new}
    ax0 = dm(new_pitch);
    mx0 = dm(new_gain);
    dm(new_pitch) = ax1;
    dm(new_gain)  = mx1;
    dm(old_pitch) = ax0;
    dm(old_gain)  = mx0;
    i6 = ^new_k;  l6 = 0;
    i5 = ^old_k;  l5 = 0;
    cntr = N;
    do move_to_old until ce;
      ay0 = pm(i6,m4), ax0 = dm(i1,m1);
      pm(i5,m5) = ay0;
    move_to_old: pm(i6,m5) = ax0;

    {setup for lattice filter}
    i0 = ^cur_k;   l0 = N;
    i4 = ^e_back;  l4 = N;
    m2 = -1;
    m6 = 3; 
    m7 = -2;

    {setup pitch_period cntr, in temp var (=af)}
    ax0 = dm(pp_cnt);
    af = pass ax0;

    {synthesize a whole frame}
    cntr = FRAME_LENGTH;
    ax0 = 0;
    dm(pif_cnt) = ax0;

    do frame_loop until ce;
      my0 = 0; {excitation default to 0}
      af = af - 1;
      if gt jump not_pitch_time;
        {time to interpolate}
        {calculate interpolation factor = pif_cnt/(FRAME_LENGTH - 1)}
        mx0 = dm(pif_cnt);
        my0 = INTERP_FACTOR;  {= 1/(FRAME_LENGHT - 1) shift -1}
        mr  = mx0 * my0 (ss); {product is in 17.15 format}
        my1 = mr0;            {get 1.15 format}

        {calc interpolated gain}
        ax0 = dm(new_gain);
        ay0 = dm(old_gain);
        ar  = ax0 - ay0;     {new - old}
        mr  = ar * my1 (ss); {(new-old)*int_factor}
        ar  = mr1 + ay0;     { + old}
        dm(cur_gain) = ar;
        
        {test for transition between voiced/unvoiced and unvoiced/voiced}
        ay0 = dm(old_pitch);
        ar  = pass ay0;
        if eq jump old_unv;
          ax0 = dm(new_pitch);
          ar  = pass ax0;
          if eq jump new_unv; 
           {voiced - voiced}
           
           {calc interpolated pitch}
            ar  = ax0 - ay0;     {new - old}
            mr  = ar * my1 (ss); {(new-old)*int_factor}
            ar  = mr1 + ay0;     { + old}
            dm(cur_pitch) = ar;
           
           {"interpolate" k's}
            i1 = ^cur_k;  l1 = 0;
            i5 = ^old_k;  l5 = 0;
            cntr = N;
            do interpolate_k until ce;
              ay0 = pm(i5,m5);
            interpolate_k: dm(i1,m1) = ay0;
          new_unv:

          {reinitialize pitch cntr}
          ar = dm(cur_pitch);
          af = pass ar;

          {set my0 = excitation impuls, in case of voiced frame}
          {multiply excitation by gain*(pitch/FRAME_LENGTH)}
          mx1 = ONE_OVER_FRAMEL;     { = 1/FRAME_LENGTH}
          my1 = dm(cur_pitch);
          mr = mx1 * my1 (ss);  {pitch/FRAME_LENGTH, result in 16.16 format}
          my1 = dm(cur_gain);   
          mr  = mr0 * my1 (ss); {gain*pitch/FRAME_LENGTH}
          my1 = 0x7fff;         {impuls}
          mr  = mr1 * my1 (ss); 
          my0 = mr1;
         
          jump not_pitch_time;

        old_unv:  {unvoiced - *}
          ax0 = 1;       {set the pitch_period cntr to a apropriate spacing}
          af  = pass ax0;
          ax0 = 0;
          dm(cur_pitch) = ax0;  {set voiced state to unvoiced}
           
         {copy old_k to cur_k}
          i1 = ^cur_k;  l1 = 0;
          i5 = ^old_k;  l5 = 0;
          cntr = N;
          do move_to_cur until ce;
            ay0 = pm(i5,m5);
          move_to_cur: dm(i1,m1) = ay0;

      not_pitch_time:
       
       {calculate driving sample if noised}
      ax0 = dm(cur_pitch);
      ar = pass ax0;      {check for voiced/unvoiced}
      if ne jump voiced;
        sr1 = dm(hi_noise_seed);  {noised, old_pitch = 0}
        sr0 = dm(lo_noise_seed);
        call noise_rand;          {random: 16 bit nr}
        dm(hi_noise_seed) = sr1;
        dm(lo_noise_seed) = sr0;
        ar  = abs sr1;
        sr  = ashift ar by -3 (hi);
        my1 = dm(cur_gain);        {multiply by gain}
        mr  = sr1 * my1 (ss);
        my0 = mr1;                 {my0 = excitation} 
        jump do_filter;                    
      voiced:   
      do_filter:
         
         {do allpole lattice filter (from apps book)}
      cntr = N - 1;
      mr = 0;
      mr1 = my0;
      mx0 = dm(i0,m1), my0 = pm(i4,m5);
      mr = mr - mx0*my0 (ss), mx0 = dm(i0,m1), my0 = pm(i4,m5);
      do dataloop until ce;
        mr = mr - mx0*my0 (ss);
        my1 = mr1, mr = 0;
        mr1 = my0;
        mr = mr + mx0*my1 (ss), mx0 = dm(i0,m1), my0 = pm(i4,m7);
        pm(i4,m6) = mr1, mr = 0;
      dataloop:  mr1 = my1;
      
      my0 = pm(i4,m7), mx0 = dm(i0,m2);
      dm(i2,m1) = my1;     {store synthesized sample}
      pm(i4,m5) = mr1;     {store newest value in delay line}

       {increment place_in_frame cntr}
      ay0 = dm(pif_cnt);
      ar  = ay0 + 1;
    frame_loop: dm(pif_cnt) = ar;

     {store pitch_period cntr for next iteration}
    ar = pass af;
    dm(pp_cnt) = ar;

  done:
  l4  = 0;
rts;
  
.endmod;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -