func: static av_cold int sonic_encode_init(AVCodecContext *avctx)
  
  {
  
      SonicContext *s = avctx->priv_data;
  
      PutBitContext pb;
  
      int i, version = 0;
  
  
  
      if (avctx->channels > MAX_CHANNELS)
  
      {
  
          av_log(avctx, AV_LOG_ERROR, "Only mono and stereo streams are supported by now\n");
  
          return AVERROR(EINVAL); /* only stereo or mono for now */
  
      }
  
  
  
      if (avctx->channels == 2)
  
          s->decorrelation = MID_SIDE;
  
      else
  
          s->decorrelation = 3;
  
  
  
      if (avctx->codec->id == AV_CODEC_ID_SONIC_LS)
  
      {
  
          s->lossless = 1;
  
          s->num_taps = 32;
  
          s->downsampling = 1;
  
          s->quantization = 0.0;
  
      }
  
      else
  
      {
  
          s->num_taps = 128;
  
          s->downsampling = 2;
  
          s->quantization = 1.0;
  
      }
  
  
  
      // max tap 2048
  
      if ((s->num_taps < 32) || (s->num_taps > 1024) ||
  
          ((s->num_taps>>5)<<5 != s->num_taps))
  
      {
  
          av_log(avctx, AV_LOG_ERROR, "Invalid number of taps\n");
  
          return AVERROR_INVALIDDATA;
  
      }
  
  
  
      // generate taps
  
      s->tap_quant = av_calloc(s->num_taps, sizeof(*s->tap_quant));
  
      for (i = 0; i < s->num_taps; i++)
  
          s->tap_quant[i] = ff_sqrt(i+1);
  
  
  
      s->channels = avctx->channels;
  
      s->samplerate = avctx->sample_rate;
  
  
  
      s->block_align = 2048LL*s->samplerate/(44100*s->downsampling);
  
      s->frame_size = s->channels*s->block_align*s->downsampling;
  
  
  
      s->tail_size = s->num_taps*s->channels;
  
      s->tail = av_calloc(s->tail_size, sizeof(*s->tail));
  
      if (!s->tail)
  
          return AVERROR(ENOMEM);
  
  
  
      s->predictor_k = av_calloc(s->num_taps, sizeof(*s->predictor_k) );
  
      if (!s->predictor_k)
  
          return AVERROR(ENOMEM);
  
  
  
      for (i = 0; i < s->channels; i++)
  
      {
  
          s->coded_samples[i] = av_calloc(s->block_align, sizeof(**s->coded_samples));
  
          if (!s->coded_samples[i])
  
              return AVERROR(ENOMEM);
  
      }
  
  
  
      s->int_samples = av_calloc(s->frame_size, sizeof(*s->int_samples));
  
  
  
      s->window_size = ((2*s->tail_size)+s->frame_size);
  
      s->window = av_calloc(s->window_size, sizeof(*s->window));
  
      if (!s->window)
  
          return AVERROR(ENOMEM);
  
  
  
      avctx->extradata = av_mallocz(16);
  
      if (!avctx->extradata)
  
          return AVERROR(ENOMEM);
  
      init_put_bits(&pb, avctx->extradata, 16*8);
  
  
  
      put_bits(&pb, 2, version); // version
  
      if (version == 1)
  
      {
  
          put_bits(&pb, 2, s->channels);
  
          put_bits(&pb, 4, code_samplerate(s->samplerate));
  
      }
  
      put_bits(&pb, 1, s->lossless);
  
      if (!s->lossless)
  
          put_bits(&pb, 3, SAMPLE_SHIFT); // XXX FIXME: sample precision
  
      put_bits(&pb, 2, s->decorrelation);
  
      put_bits(&pb, 2, s->downsampling);
  
      put_bits(&pb, 5, (s->num_taps >> 5)-1); // 32..1024
  
      put_bits(&pb, 1, 0); // XXX FIXME: no custom tap quant table
  
  
  
      flush_put_bits(&pb);
  
      avctx->extradata_size = put_bits_count(&pb)/8;
  
  
  
      av_log(avctx, AV_LOG_INFO, "Sonic: ver: %d ls: %d dr: %d taps: %d block: %d frame: %d downsamp: %d\n",
  
          version, s->lossless, s->decorrelation, s->num_taps, s->block_align, s->frame_size, s->downsampling);
  
  
  
      avctx->frame_size = s->block_align*s->downsampling;
  
  
  
      return 0;
  
  }
  