static gboolean
gst_vorbis_enc_setup (GstVorbisEnc * vorbisenc)
{

  GST_LOG_OBJECT (vorbisenc, "setup");

  if (vorbisenc->bitrate < 0 && vorbisenc->min_bitrate < 0
      && vorbisenc->max_bitrate < 0) {
    vorbisenc->quality_set = TRUE;
  }

  update_start_message (vorbisenc);

  /* choose an encoding mode */
  /* (mode 0: 44kHz stereo uncoupled, roughly 128kbps VBR) */
  vorbis_info_init (&vorbisenc->vi);

  if (vorbisenc->quality_set) {
    if (vorbis_encode_setup_vbr (&vorbisenc->vi,
            vorbisenc->channels, vorbisenc->frequency,
            vorbisenc->quality) != 0) {
      GST_ERROR_OBJECT (vorbisenc,
          "vorbisenc: initialisation failed: invalid parameters for quality");
      vorbis_info_clear (&vorbisenc->vi);
      return FALSE;
    }

    /* do we have optional hard quality restrictions? */
    if (vorbisenc->max_bitrate > 0 || vorbisenc->min_bitrate > 0) {
      struct ovectl_ratemanage_arg ai;

      vorbis_encode_ctl (&vorbisenc->vi, OV_ECTL_RATEMANAGE_GET, &ai);

      ai.bitrate_hard_min = vorbisenc->min_bitrate;
      ai.bitrate_hard_max = vorbisenc->max_bitrate;
      ai.management_active = 1;

      vorbis_encode_ctl (&vorbisenc->vi, OV_ECTL_RATEMANAGE_SET, &ai);
    }
  } else {
    long min_bitrate, max_bitrate;

    min_bitrate = vorbisenc->min_bitrate > 0 ? vorbisenc->min_bitrate : -1;
    max_bitrate = vorbisenc->max_bitrate > 0 ? vorbisenc->max_bitrate : -1;

    if (vorbis_encode_setup_managed (&vorbisenc->vi,
            vorbisenc->channels,
            vorbisenc->frequency,
            max_bitrate, vorbisenc->bitrate, min_bitrate) != 0) {
      GST_ERROR_OBJECT (vorbisenc,
          "vorbis_encode_setup_managed "
          "(c %d, rate %d, max br %ld, br %d, min br %ld) failed",
          vorbisenc->channels, vorbisenc->frequency, max_bitrate,
          vorbisenc->bitrate, min_bitrate);
      vorbis_info_clear (&vorbisenc->vi);
      return FALSE;
    }
  }

  if (vorbisenc->managed && vorbisenc->bitrate < 0) {
    vorbis_encode_ctl (&vorbisenc->vi, OV_ECTL_RATEMANAGE_AVG, NULL);
  } else if (!vorbisenc->managed) {
    /* Turn off management entirely (if it was turned on). */
    vorbis_encode_ctl (&vorbisenc->vi, OV_ECTL_RATEMANAGE_SET, NULL);
  }
  vorbis_encode_setup_init (&vorbisenc->vi);

  /* set up the analysis state and auxiliary encoding storage */
  vorbis_analysis_init (&vorbisenc->vd, &vorbisenc->vi);
  vorbis_block_init (&vorbisenc->vd, &vorbisenc->vb);

  /* samples == granulepos start at 0 again */
  vorbisenc->samples_out = 0;

  /* fresh encoder available */
  vorbisenc->setup = TRUE;

  return TRUE;
}
static gboolean
xing_mp3_encoder_setup(XingMp3Encoder *encoder)
{
    E_CONTROL *control;

    update_start_message(encoder);

    control = g_new0(E_CONTROL, 1);

    if(encoder->channels == 1) {
        control->mode                = 3;     /* mode-0 stereo=0 mode-1 stereo=1 dual=2 mono=3 */
    } else { /* encoder->channels == 2 */
        control->mode                = 0;     /* mode-0 stereo=0 mode-1 stereo=1 dual=2 mono=3 */
    }
    
    control->samprate              = encoder->frequency;  /* sample rate e.g 44100 */
    control->nsbstereo             = -1;    /* mode-1 only, stereo bands, 3-32 , for default set =-1 */
    control->filter_select         = -1;    /* input filter selection - set to -1 for default */
    control->freq_limit            = 24000; /* special purpose, set to 24000 */
    control->nsb_limit             = -1;    /* special purpose, set to -1 */
    control->layer                 = 3;     /* 3=Layer III. Set to 3 */
    control->cr_bit                = 0;     /* header copyright bit setting */
    control->original              = 1;     /* header original/copy bit setting, original=1 */
    control->hf_flag               = 24000; /* MPEG1 high frequency */
    control->vbr_mnr               = 50;    /* 0-150, suggested setting is 50 */
    control->vbr_br_limit          = 160;   /* reserved for per chan vbr bitrate limit set to 160 */
    control->vbr_delta_mnr         = 0;     /* special, set 0 default */
    control->chan_add_f0           = 24000; /* channel adder start freq - set 24000 default */
    control->chan_add_f1           = 24000; /* channel adder final freq - set 24000 default */
    control->sparse_scale          = -1;    /* reserved set, to -1 (encoder chooses) */
    /* control->mnr_adjust[21]; */          /* special, set 0 default */
    control->cpu_select            = 0;     /* 0=generic, 1=3DNow reserved, 2=Pentium III */
    control->quick                 = -1;    /* 0 = base, 1 = fast, -1 = encoder chooses */
    control->test1                 = -1;    /* special test, set to -1 */
    control->test2                 = 0;     /* special test, set to 0 */
    control->test3                 = 0;     /* special test, set to 0 */
    control->short_block_threshold = 700;   /* short_block_threshold, default 700 */

    if(encoder->use_cbr) {
        control->vbr_flag = FALSE;
        control->bitrate = (encoder->cbr_bitrate != BITRATE_DEFAULT)
            ? encoder->cbr_bitrate / 2  // Per channel bitrate in 1000s
            : -1;
    } else {
        control->vbr_flag = TRUE;  // 1=vbr, 0=cbr  
        control->bitrate = -1;     // Per channel bitrate in 1000s, CBR only. -1 = default. 
    } 

    encoder->xing_encoder = hx_mp3enc_new();
    encoder->bytes_per_frame =
        hx_mp3enc_mp3_init(encoder->xing_encoder, control,
                        0 /* 16 bits per sample */,
                        0 /* upsample for... default */,
                        0 /* convert to mono? */);

    encoder->input_buffer = g_malloc(INPUT_BUFFER_SIZE);
    encoder->input_buffer_pos = 0;

    encoder->is_initialized = TRUE;

    return TRUE;
}