예제 #1
0
void WebRtcIsacfix_PitchAnalysis(const int16_t *inn,               /* PITCH_FRAME_LEN samples */
                                 int16_t *outQ0,                  /* PITCH_FRAME_LEN+QLOOKAHEAD samples */
                                 PitchAnalysisStruct *State,
                                 int16_t *PitchLags_Q7,
                                 int16_t *PitchGains_Q12)
{
  int16_t inbufQ0[PITCH_FRAME_LEN + QLOOKAHEAD];
  int16_t k;

  /* inital pitch estimate */
  WebRtcIsacfix_InitialPitch(inn, State,  PitchLags_Q7);


  /* Calculate gain */
  WebRtcIsacfix_PitchFilterGains(inn, &(State->PFstr_wght), PitchLags_Q7, PitchGains_Q12);

  /* concatenate previous input's end and current input */
  for (k = 0; k < QLOOKAHEAD; k++) {
    inbufQ0[k] = State->inbuf[k];
  }
  for (k = 0; k < PITCH_FRAME_LEN; k++) {
    inbufQ0[k+QLOOKAHEAD] = (int16_t) inn[k];
  }

  /* lookahead pitch filtering for masking analysis */
  WebRtcIsacfix_PitchFilter(inbufQ0, outQ0, &(State->PFstr), PitchLags_Q7,PitchGains_Q12, 2);


  /* store last part of input */
  for (k = 0; k < QLOOKAHEAD; k++) {
    State->inbuf[k] = inbufQ0[k + PITCH_FRAME_LEN];
  }
}
예제 #2
0
int WebRtcIsacfix_EncodeImpl(int16_t      *in,
                             ISACFIX_EncInst_t  *ISACenc_obj,
                             BwEstimatorstr      *bw_estimatordata,
                             int16_t         CodingMode)
{
  int16_t stream_length = 0;
  int16_t usefulstr_len = 0;
  int k;
  int16_t BWno;

  int16_t lofilt_coefQ15[(ORDERLO)*SUBFRAMES];
  int16_t hifilt_coefQ15[(ORDERHI)*SUBFRAMES];
  int32_t gain_lo_hiQ17[2*SUBFRAMES];

  int16_t LPandHP[FRAMESAMPLES/2 + QLOOKAHEAD];
  int16_t LP16a[FRAMESAMPLES/2 + QLOOKAHEAD];
  int16_t HP16a[FRAMESAMPLES/2 + QLOOKAHEAD];

  int16_t PitchLags_Q7[PITCH_SUBFRAMES];
  int16_t PitchGains_Q12[PITCH_SUBFRAMES];
  int16_t AvgPitchGain_Q12;

  int16_t frame_mode; /* 0 for 30ms, 1 for 60ms */
  int16_t processed_samples;
  int status;

  int32_t bits_gainsQ11;
  int16_t MinBytes;
  int16_t bmodel;

  transcode_obj transcodingParam;
  int16_t payloadLimitBytes;
  int16_t arithLenBeforeEncodingDFT;
  int16_t iterCntr;

  /* copy new frame length and bottle neck rate only for the first 10 ms data */
  if (ISACenc_obj->buffer_index == 0) {
    /* set the framelength for the next packet */
    ISACenc_obj->current_framesamples = ISACenc_obj->new_framelength;
  }

  frame_mode = ISACenc_obj->current_framesamples/MAX_FRAMESAMPLES; /* 0 (30 ms) or 1 (60 ms)  */
  processed_samples = ISACenc_obj->current_framesamples/(frame_mode+1); /* 480 (30, 60 ms) */

  /* buffer speech samples (by 10ms packet) until the framelength is reached (30 or 60 ms) */
  /**************************************************************************************/
  /* fill the buffer with 10ms input data */
  for(k=0; k<FRAMESAMPLES_10ms; k++) {
    ISACenc_obj->data_buffer_fix[k + ISACenc_obj->buffer_index] = in[k];
  }
  /* if buffersize is not equal to current framesize, and end of file is not reached yet, */
  /* increase index and go back to main to get more speech samples */
  if (ISACenc_obj->buffer_index + FRAMESAMPLES_10ms != processed_samples) {
    ISACenc_obj->buffer_index = ISACenc_obj->buffer_index + FRAMESAMPLES_10ms;
    return 0;
  }
  /* if buffer reached the right size, reset index and continue with encoding the frame */
  ISACenc_obj->buffer_index = 0;

  /* end of buffer function */
  /**************************/

  /* encoding */
  /************/

  if (frame_mode == 0 || ISACenc_obj->frame_nb == 0 )
  {
    /* reset bitstream */
    ISACenc_obj->bitstr_obj.W_upper = 0xFFFFFFFF;
    ISACenc_obj->bitstr_obj.streamval = 0;
    ISACenc_obj->bitstr_obj.stream_index = 0;
    ISACenc_obj->bitstr_obj.full = 1;

    if (CodingMode == 0) {
      ISACenc_obj->BottleNeck =  WebRtcIsacfix_GetUplinkBandwidth(bw_estimatordata);
      ISACenc_obj->MaxDelay =  WebRtcIsacfix_GetUplinkMaxDelay(bw_estimatordata);
    }
    if (CodingMode == 0 && frame_mode == 0 && (ISACenc_obj->enforceFrameSize == 0)) {
      ISACenc_obj->new_framelength = WebRtcIsacfix_GetNewFrameLength(ISACenc_obj->BottleNeck,
                                                                     ISACenc_obj->current_framesamples);
    }

    // multiply the bottleneck by 0.88 before computing SNR, 0.88 is tuned by experimenting on TIMIT
    // 901/1024 is 0.87988281250000
    ISACenc_obj->s2nr = WebRtcIsacfix_GetSnr((int16_t)WEBRTC_SPL_MUL_16_16_RSFT(ISACenc_obj->BottleNeck, 901, 10),
                                             ISACenc_obj->current_framesamples);

    /* encode frame length */
    status = WebRtcIsacfix_EncodeFrameLen(ISACenc_obj->current_framesamples, &ISACenc_obj->bitstr_obj);
    if (status < 0)
    {
      /* Wrong frame size */
      if (frame_mode == 1 && ISACenc_obj->frame_nb == 1)
      {
        // If this is the second 30ms of a 60ms frame reset this such that in the next call
        // encoder starts fresh.
        ISACenc_obj->frame_nb = 0;
      }
      return status;
    }

    /* Save framelength for multiple packets memory */
    if (ISACenc_obj->SaveEnc_ptr != NULL) {
      (ISACenc_obj->SaveEnc_ptr)->framelength=ISACenc_obj->current_framesamples;
    }

    /* bandwidth estimation and coding */
    BWno = WebRtcIsacfix_GetDownlinkBwIndexImpl(bw_estimatordata);
    status = WebRtcIsacfix_EncodeReceiveBandwidth(&BWno, &ISACenc_obj->bitstr_obj);
    if (status < 0)
    {
      if (frame_mode == 1 && ISACenc_obj->frame_nb == 1)
      {
        // If this is the second 30ms of a 60ms frame reset this such that in the next call
        // encoder starts fresh.
        ISACenc_obj->frame_nb = 0;
      }
      return status;
    }
  }

  /* split signal in two bands */
  WebRtcIsacfix_SplitAndFilter1(ISACenc_obj->data_buffer_fix, LP16a, HP16a, &ISACenc_obj->prefiltbankstr_obj );

  /* estimate pitch parameters and pitch-filter lookahead signal */
  WebRtcIsacfix_PitchAnalysis(LP16a+QLOOKAHEAD, LPandHP,
                              &ISACenc_obj->pitchanalysisstr_obj,  PitchLags_Q7, PitchGains_Q12); /* LPandHP = LP_lookahead_pfQ0, */

  /* Set where to store data in multiple packets memory */
  if (ISACenc_obj->SaveEnc_ptr != NULL) {
    if (frame_mode == 0 || ISACenc_obj->frame_nb == 0)
    {
      (ISACenc_obj->SaveEnc_ptr)->startIdx = 0;
    }
    else
    {
      (ISACenc_obj->SaveEnc_ptr)->startIdx = 1;
    }
  }

  /* quantize & encode pitch parameters */
  status = WebRtcIsacfix_EncodePitchGain(PitchGains_Q12, &ISACenc_obj->bitstr_obj,  ISACenc_obj->SaveEnc_ptr);
  if (status < 0)
  {
    if (frame_mode == 1 && ISACenc_obj->frame_nb == 1)
    {
      // If this is the second 30ms of a 60ms frame reset this such that in the next call
      // encoder starts fresh.
      ISACenc_obj->frame_nb = 0;
    }
    return status;
  }
  status = WebRtcIsacfix_EncodePitchLag(PitchLags_Q7 , PitchGains_Q12, &ISACenc_obj->bitstr_obj,  ISACenc_obj->SaveEnc_ptr);
  if (status < 0)
  {
    if (frame_mode == 1 && ISACenc_obj->frame_nb == 1)
    {
      // If this is the second 30ms of a 60ms frame reset this such that in the next call
      // encoder starts fresh.
      ISACenc_obj->frame_nb = 0;
    }
    return status;
  }
  AvgPitchGain_Q12 = WEBRTC_SPL_RSHIFT_W32(PitchGains_Q12[0] + PitchGains_Q12[1] + PitchGains_Q12[2] + PitchGains_Q12[3], 2);

  /* find coefficients for perceptual pre-filters */
  WebRtcIsacfix_GetLpcCoef(LPandHP, HP16a+QLOOKAHEAD, &ISACenc_obj->maskfiltstr_obj,
                           ISACenc_obj->s2nr, PitchGains_Q12,
                           gain_lo_hiQ17, lofilt_coefQ15, hifilt_coefQ15); /*LPandHP = LP_lookahead_pfQ0*/

  // record LPC Gains for possible bit-rate reduction
  for(k = 0; k < KLT_ORDER_GAIN; k++)
  {
    transcodingParam.lpcGains[k] = gain_lo_hiQ17[k];
  }

  /* code LPC model and shape - gains not quantized yet */
  status = WebRtcIsacfix_EncodeLpc(gain_lo_hiQ17, lofilt_coefQ15, hifilt_coefQ15,
                                   &bmodel, &bits_gainsQ11, &ISACenc_obj->bitstr_obj, ISACenc_obj->SaveEnc_ptr, &transcodingParam);
  if (status < 0)
  {
    if (frame_mode == 1 && ISACenc_obj->frame_nb == 1)
    {
      // If this is the second 30ms of a 60ms frame reset this such that in the next call
      // encoder starts fresh.
      ISACenc_obj->frame_nb = 0;
    }
    return status;
  }
  arithLenBeforeEncodingDFT = (ISACenc_obj->bitstr_obj.stream_index << 1) + (1-ISACenc_obj->bitstr_obj.full);

  /* low-band filtering */
  WebRtcIsacfix_NormLatticeFilterMa(ORDERLO, ISACenc_obj->maskfiltstr_obj.PreStateLoGQ15,
                                    LP16a, lofilt_coefQ15, gain_lo_hiQ17, 0, LPandHP);/* LPandHP = LP16b */

  /* pitch filter */
  WebRtcIsacfix_PitchFilter(LPandHP, LP16a, &ISACenc_obj->pitchfiltstr_obj, PitchLags_Q7, PitchGains_Q12, 1);/* LPandHP = LP16b */

  /* high-band filtering */
  WebRtcIsacfix_NormLatticeFilterMa(ORDERHI, ISACenc_obj->maskfiltstr_obj.PreStateHiGQ15,
                                    HP16a, hifilt_coefQ15, gain_lo_hiQ17, 1, LPandHP);/*LPandHP = HP16b*/

  /* transform */
  WebRtcIsacfix_Time2Spec(LP16a, LPandHP, LP16a, LPandHP); /*LPandHP = HP16b*/

  /* Save data for multiple packets memory */
  if (ISACenc_obj->SaveEnc_ptr != NULL) {
    for (k = 0; k < FRAMESAMPLES_HALF; k++) {
      (ISACenc_obj->SaveEnc_ptr)->fre[k + (ISACenc_obj->SaveEnc_ptr)->startIdx*FRAMESAMPLES_HALF] = LP16a[k];
      (ISACenc_obj->SaveEnc_ptr)->fim[k + (ISACenc_obj->SaveEnc_ptr)->startIdx*FRAMESAMPLES_HALF] = LPandHP[k];
    }
    (ISACenc_obj->SaveEnc_ptr)->AvgPitchGain[(ISACenc_obj->SaveEnc_ptr)->startIdx] = AvgPitchGain_Q12;
  }

  /* quantization and lossless coding */
  status = WebRtcIsacfix_EncodeSpec(LP16a, LPandHP, &ISACenc_obj->bitstr_obj, AvgPitchGain_Q12);
  if((status <= -1) && (status != -ISAC_DISALLOWED_BITSTREAM_LENGTH)) /*LPandHP = HP16b*/
  {
    if (frame_mode == 1 && ISACenc_obj->frame_nb == 1)
    {
      // If this is the second 30ms of a 60ms frame reset this such that in the next call
      // encoder starts fresh.
      ISACenc_obj->frame_nb = 0;
    }
    return status;
  }

  if((frame_mode == 1) && (ISACenc_obj->frame_nb == 0))
  {
    // it is a 60ms and we are in the first 30ms
    // then the limit at this point should be half of the assigned value
    payloadLimitBytes = ISACenc_obj->payloadLimitBytes60 >> 1;
  }
예제 #3
0
파일: decode.c 프로젝트: Valbonjv/QuickSMS
int16_t WebRtcIsacfix_DecodeImpl(int16_t       *signal_out16,
                                 ISACFIX_DecInst_t *ISACdec_obj,
                                 int16_t       *current_framesamples)
{
  int k;
  int err;
  int16_t BWno;
  int16_t len = 0;

  int16_t model;


  int16_t Vector_Word16_1[FRAMESAMPLES/2];
  int16_t Vector_Word16_2[FRAMESAMPLES/2];

  int32_t Vector_Word32_1[FRAMESAMPLES/2];
  int32_t Vector_Word32_2[FRAMESAMPLES/2];

  int16_t lofilt_coefQ15[ORDERLO*SUBFRAMES]; //refl. coeffs
  int16_t hifilt_coefQ15[ORDERHI*SUBFRAMES]; //refl. coeffs
  int32_t gain_lo_hiQ17[2*SUBFRAMES];

  int16_t PitchLags_Q7[PITCH_SUBFRAMES];
  int16_t PitchGains_Q12[PITCH_SUBFRAMES];
  int16_t AvgPitchGain_Q12;

  int16_t tmp_1, tmp_2;
  int32_t tmp32a, tmp32b;
  int16_t gainQ13;


  int16_t frame_nb; /* counter */
  int16_t frame_mode; /* 0 for 20ms and 30ms, 1 for 60ms */
  int16_t processed_samples;

  /* PLC */
  int16_t overlapWin[ 240 ];

  (ISACdec_obj->bitstr_obj).W_upper = 0xFFFFFFFF;
  (ISACdec_obj->bitstr_obj).streamval = 0;
  (ISACdec_obj->bitstr_obj).stream_index = 0;
  (ISACdec_obj->bitstr_obj).full = 1;


  /* decode framelength and BW estimation - not used, only for stream pointer*/
  err = WebRtcIsacfix_DecodeFrameLen(&ISACdec_obj->bitstr_obj, current_framesamples);
  if (err<0)  // error check
    return err;

  frame_mode = (int16_t)WEBRTC_SPL_DIV(*current_framesamples, MAX_FRAMESAMPLES); /* 0, or 1 */
  processed_samples = (int16_t)WEBRTC_SPL_DIV(*current_framesamples, frame_mode+1); /* either 320 (20ms) or 480 (30, 60 ms) */

  err = WebRtcIsacfix_DecodeSendBandwidth(&ISACdec_obj->bitstr_obj, &BWno);
  if (err<0)  // error check
    return err;

  /* one loop if it's one frame (20 or 30ms), 2 loops if 2 frames bundled together (60ms) */
  for (frame_nb = 0; frame_nb <= frame_mode; frame_nb++) {

    /* decode & dequantize pitch parameters */
    err = WebRtcIsacfix_DecodePitchGain(&(ISACdec_obj->bitstr_obj), PitchGains_Q12);
    if (err<0)  // error check
      return err;

    err = WebRtcIsacfix_DecodePitchLag(&ISACdec_obj->bitstr_obj, PitchGains_Q12, PitchLags_Q7);
    if (err<0)  // error check
      return err;

    AvgPitchGain_Q12 = (int16_t)(((int32_t)PitchGains_Q12[0] + PitchGains_Q12[1] + PitchGains_Q12[2] + PitchGains_Q12[3])>>2);

    /* decode & dequantize FiltCoef */
    err = WebRtcIsacfix_DecodeLpc(gain_lo_hiQ17, lofilt_coefQ15, hifilt_coefQ15,
                                  &ISACdec_obj->bitstr_obj, &model);

    if (err<0)  // error check
      return err;

    /* decode & dequantize spectrum */
    len = WebRtcIsacfix_DecodeSpec(&ISACdec_obj->bitstr_obj, Vector_Word16_1, Vector_Word16_2, AvgPitchGain_Q12);
    if (len < 0)  // error check
      return len;

    // Why does this need Q16 in and out? /JS
    WebRtcIsacfix_Spec2Time(Vector_Word16_1, Vector_Word16_2, Vector_Word32_1, Vector_Word32_2);

    for (k=0; k<FRAMESAMPLES/2; k++) {
      Vector_Word16_1[k] = (int16_t)WEBRTC_SPL_RSHIFT_W32(Vector_Word32_1[k]+64, 7); //Q16 -> Q9
    }

    /* ----  If this is recovery frame ---- */
    if( (ISACdec_obj->plcstr_obj).used == PLC_WAS_USED )
    {
      (ISACdec_obj->plcstr_obj).used = PLC_NOT_USED;
      if( (ISACdec_obj->plcstr_obj).B < 1000 )
      {
        (ISACdec_obj->plcstr_obj).decayCoeffPriodic = 4000;
      }

      ISACdec_obj->plcstr_obj.decayCoeffPriodic = WEBRTC_SPL_WORD16_MAX;    /* DECAY_RATE is in Q15 */
      ISACdec_obj->plcstr_obj.decayCoeffNoise = WEBRTC_SPL_WORD16_MAX;    /* DECAY_RATE is in Q15 */
      ISACdec_obj->plcstr_obj.pitchCycles = 0;

      PitchGains_Q12[0] = (int16_t)WEBRTC_SPL_MUL_16_16_RSFT(PitchGains_Q12[0], 700, 10 );

      /* ---- Add-overlap ---- */
      WebRtcSpl_GetHanningWindow( overlapWin, RECOVERY_OVERLAP );
      for( k = 0; k < RECOVERY_OVERLAP; k++ )
        Vector_Word16_1[k] = WebRtcSpl_AddSatW16(
            (int16_t)WEBRTC_SPL_MUL_16_16_RSFT( (ISACdec_obj->plcstr_obj).overlapLP[k], overlapWin[RECOVERY_OVERLAP - k - 1], 14),
            (int16_t)WEBRTC_SPL_MUL_16_16_RSFT( Vector_Word16_1[k], overlapWin[k], 14) );



    }

    /* --- Store side info --- */
    if( frame_nb == frame_mode )
    {
      /* --- LPC info */
      WEBRTC_SPL_MEMCPY_W16( (ISACdec_obj->plcstr_obj).lofilt_coefQ15, &lofilt_coefQ15[(SUBFRAMES-1)*ORDERLO], ORDERLO );
      WEBRTC_SPL_MEMCPY_W16( (ISACdec_obj->plcstr_obj).hifilt_coefQ15, &hifilt_coefQ15[(SUBFRAMES-1)*ORDERHI], ORDERHI );
      (ISACdec_obj->plcstr_obj).gain_lo_hiQ17[0] = gain_lo_hiQ17[(SUBFRAMES-1) * 2];
      (ISACdec_obj->plcstr_obj).gain_lo_hiQ17[1] = gain_lo_hiQ17[(SUBFRAMES-1) * 2 + 1];

      /* --- LTP info */
      (ISACdec_obj->plcstr_obj).AvgPitchGain_Q12 = PitchGains_Q12[3];
      (ISACdec_obj->plcstr_obj).lastPitchGain_Q12 = PitchGains_Q12[3];
      (ISACdec_obj->plcstr_obj).lastPitchLag_Q7 = PitchLags_Q7[3];

      if( PitchLags_Q7[3] < 3000 )
        (ISACdec_obj->plcstr_obj).lastPitchLag_Q7 += PitchLags_Q7[3];

      WEBRTC_SPL_MEMCPY_W16( (ISACdec_obj->plcstr_obj).prevPitchInvIn, Vector_Word16_1, FRAMESAMPLES/2 );

    }
    /* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */

    /* inverse pitch filter */
    WebRtcIsacfix_PitchFilter(Vector_Word16_1, Vector_Word16_2, &ISACdec_obj->pitchfiltstr_obj, PitchLags_Q7, PitchGains_Q12, 4);

    if( frame_nb == frame_mode )
    {
      WEBRTC_SPL_MEMCPY_W16( (ISACdec_obj->plcstr_obj).prevPitchInvOut, &(Vector_Word16_2[FRAMESAMPLES/2 - (PITCH_MAX_LAG + 10)]), PITCH_MAX_LAG );
    }


    /* reduce gain to compensate for pitch enhancer */
    /* gain = 1.0f - 0.45f * AvgPitchGain; */
    tmp32a = WEBRTC_SPL_MUL_16_16_RSFT(AvgPitchGain_Q12, 29, 0); // Q18
    tmp32b = 262144 - tmp32a;  // Q18
    gainQ13 = (int16_t) WEBRTC_SPL_RSHIFT_W32(tmp32b, 5); // Q13

    for (k = 0; k < FRAMESAMPLES/2; k++)
    {
      Vector_Word32_1[k] = (int32_t) WEBRTC_SPL_LSHIFT_W32(WEBRTC_SPL_MUL_16_16(Vector_Word16_2[k], gainQ13), 3); // Q25
    }


    /* perceptual post-filtering (using normalized lattice filter) */
    WebRtcIsacfix_NormLatticeFilterAr(ORDERLO, (ISACdec_obj->maskfiltstr_obj).PostStateLoGQ0,
                                      Vector_Word32_1, lofilt_coefQ15, gain_lo_hiQ17, 0, Vector_Word16_1);

    /* --- Store Highpass Residual --- */
    for (k = 0; k < FRAMESAMPLES/2; k++)
      Vector_Word32_1[k]    = WEBRTC_SPL_LSHIFT_W32(Vector_Word32_2[k], 9); // Q16 -> Q25

    for( k = 0; k < PITCH_MAX_LAG + 10; k++ )
      (ISACdec_obj->plcstr_obj).prevHP[k] = Vector_Word32_1[FRAMESAMPLES/2 - (PITCH_MAX_LAG + 10) + k];


    WebRtcIsacfix_NormLatticeFilterAr(ORDERHI, (ISACdec_obj->maskfiltstr_obj).PostStateHiGQ0,
                                      Vector_Word32_1, hifilt_coefQ15, gain_lo_hiQ17, 1, Vector_Word16_2);

    /* recombine the 2 bands */

    /* Form the polyphase signals, and compensate for DC offset */
    for (k=0;k<FRAMESAMPLES/2;k++) {
      tmp_1 = (int16_t)WebRtcSpl_SatW32ToW16(((int32_t)Vector_Word16_1[k]+Vector_Word16_2[k] + 1)); /* Construct a new upper channel signal*/
      tmp_2 = (int16_t)WebRtcSpl_SatW32ToW16(((int32_t)Vector_Word16_1[k]-Vector_Word16_2[k])); /* Construct a new lower channel signal*/
      Vector_Word16_1[k] = tmp_1;
      Vector_Word16_2[k] = tmp_2;
    }

    WebRtcIsacfix_FilterAndCombine1(Vector_Word16_1, Vector_Word16_2, signal_out16 + frame_nb * processed_samples, &ISACdec_obj->postfiltbankstr_obj);

  }
  return len;
}