Ejemplo n.º 1
0
gboolean
audio_convert_prepare_context (AudioConvertCtx * ctx, AudioConvertFmt * in,
    AudioConvertFmt * out, GstAudioConvertDithering dither,
    GstAudioConvertNoiseShaping ns)
{
  gint idx_in, idx_out;

  g_return_val_if_fail (ctx != NULL, FALSE);
  g_return_val_if_fail (in != NULL, FALSE);
  g_return_val_if_fail (out != NULL, FALSE);

  /* first clean the existing context */
  audio_convert_clean_context (ctx);

  g_return_val_if_fail (in->unpositioned_layout == out->unpositioned_layout,
      FALSE);

  ctx->in = *in;
  ctx->out = *out;

  /* Don't dither or apply noise shaping if target depth is bigger than 20 bits
   * as DA converters only can do a SNR up to 20 bits in reality.
   * Also don't dither or apply noise shaping if target depth is larger than
   * source depth. */
  if (ctx->out.depth <= 20 && (!ctx->in.is_int
          || ctx->in.depth >= ctx->out.depth)) {
    ctx->dither = dither;
    ctx->ns = ns;
  } else {
    ctx->dither = DITHER_NONE;
    ctx->ns = NOISE_SHAPING_NONE;
  }

  /* Use simple error feedback when output sample rate is smaller than
   * 32000 as the other methods might move the noise to audible ranges */
  if (ctx->ns > NOISE_SHAPING_ERROR_FEEDBACK && ctx->out.rate < 32000)
    ctx->ns = NOISE_SHAPING_ERROR_FEEDBACK;

  gst_channel_mix_setup_matrix (ctx);

  idx_in = audio_convert_get_func_index (ctx, in);
  ctx->unpack = unpack_funcs[idx_in];

  idx_out = audio_convert_get_func_index (ctx, out);
  ctx->pack = pack_funcs[idx_out];

  /* if both formats are float/double or we use noise shaping use double as
   * intermediate format and and switch mixing */
  if (!DOUBLE_INTERMEDIATE_FORMAT (ctx)) {
    GST_INFO ("use int mixing");
    ctx->channel_mix = (AudioConvertMix) gst_channel_mix_mix_int;
  } else {
    GST_INFO ("use float mixing");
    ctx->channel_mix = (AudioConvertMix) gst_channel_mix_mix_float;
  }
  GST_INFO ("unitsizes: %d -> %d", in->unit_size, out->unit_size);

  /* check if input is in default format */
  ctx->in_default = check_default (ctx, in);
  /* check if channel mixer is passthrough */
  ctx->mix_passthrough = gst_channel_mix_passthrough (ctx);
  /* check if output is in default format */
  ctx->out_default = check_default (ctx, out);

  GST_INFO ("in default %d, mix passthrough %d, out default %d",
      ctx->in_default, ctx->mix_passthrough, ctx->out_default);

  ctx->in_scale = (in->is_int) ? (32 - in->depth) : 0;
  ctx->out_scale = (out->is_int) ? (32 - out->depth) : 0;

  gst_audio_quantize_setup (ctx);

  return TRUE;
}
Ejemplo n.º 2
0
gboolean
audio_convert_prepare_context (AudioConvertCtx * ctx, GstAudioInfo * in,
    GstAudioInfo * out, GstAudioConvertDithering dither,
    GstAudioConvertNoiseShaping ns)
{
  gint idx_in, idx_out;
  gint in_depth, out_depth;

  g_return_val_if_fail (ctx != NULL, FALSE);
  g_return_val_if_fail (in != NULL, FALSE);
  g_return_val_if_fail (out != NULL, FALSE);

  /* first clean the existing context */
  audio_convert_clean_context (ctx);
  if ((GST_AUDIO_INFO_CHANNELS (in) != GST_AUDIO_INFO_CHANNELS (out)) &&
      (GST_AUDIO_INFO_IS_UNPOSITIONED (in)
          || GST_AUDIO_INFO_IS_UNPOSITIONED (out)))
    goto unpositioned;

  ctx->in = *in;
  ctx->out = *out;

  in_depth = GST_AUDIO_FORMAT_INFO_DEPTH (in->finfo);
  out_depth = GST_AUDIO_FORMAT_INFO_DEPTH (out->finfo);

  GST_INFO ("depth in %d, out %d", in_depth, out_depth);

  /* Don't dither or apply noise shaping if target depth is bigger than 20 bits
   * as DA converters only can do a SNR up to 20 bits in reality.
   * Also don't dither or apply noise shaping if target depth is larger than
   * source depth. */
  if (out_depth <= 20 && (!GST_AUDIO_FORMAT_INFO_IS_INTEGER (in->finfo)
          || in_depth >= out_depth)) {
    ctx->dither = dither;
    ctx->ns = ns;
    GST_INFO ("using dither %d and noise shaping %d", dither, ns);
  } else {
    ctx->dither = DITHER_NONE;
    ctx->ns = NOISE_SHAPING_NONE;
    GST_INFO ("using no dither and noise shaping");
  }

  /* Use simple error feedback when output sample rate is smaller than
   * 32000 as the other methods might move the noise to audible ranges */
  if (ctx->ns > NOISE_SHAPING_ERROR_FEEDBACK && out->rate < 32000)
    ctx->ns = NOISE_SHAPING_ERROR_FEEDBACK;

  gst_channel_mix_setup_matrix (ctx);

  idx_in = audio_convert_get_func_index (ctx, in->finfo);
  ctx->unpack = unpack_funcs[idx_in];

  idx_out = audio_convert_get_func_index (ctx, out->finfo);
  ctx->pack = pack_funcs[idx_out];

  GST_INFO ("func index in %d, out %d", idx_in, idx_out);

  /* if both formats are float/double or we use noise shaping use double as
   * intermediate format and switch mixing */
  if (!DOUBLE_INTERMEDIATE_FORMAT (ctx)) {
    GST_INFO ("use int mixing");
    ctx->channel_mix = (AudioConvertMix) gst_channel_mix_mix_int;
  } else {
    GST_INFO ("use float mixing");
    ctx->channel_mix = (AudioConvertMix) gst_channel_mix_mix_float;
  }
  GST_INFO ("unitsizes: %d -> %d", in->bpf, out->bpf);

  /* check if input is in default format */
  ctx->in_default = check_default (ctx, in->finfo);
  /* check if channel mixer is passthrough */
  ctx->mix_passthrough = gst_channel_mix_passthrough (ctx);
  /* check if output is in default format */
  ctx->out_default = check_default (ctx, out->finfo);

  GST_INFO ("in default %d, mix passthrough %d, out default %d",
      ctx->in_default, ctx->mix_passthrough, ctx->out_default);

  ctx->in_scale =
      GST_AUDIO_FORMAT_INFO_IS_INTEGER (in->finfo) ? (32 - in_depth) : 0;
  ctx->out_scale =
      GST_AUDIO_FORMAT_INFO_IS_INTEGER (out->finfo) ? (32 - out_depth) : 0;

  GST_INFO ("scale in %d, out %d", ctx->in_scale, ctx->out_scale);

  gst_audio_quantize_setup (ctx);

  return TRUE;

  /* ERRORS */
unpositioned:
  {
    GST_WARNING ("unpositioned channels");
    return FALSE;
  }
}