示例#1
0
static gboolean
gst_iir_equalizer_setup (GstAudioFilter * audio, const GstAudioInfo * info)
{
    GstIirEqualizer *equ = GST_IIR_EQUALIZER (audio);

    switch (GST_AUDIO_INFO_FORMAT (info)) {
    case GST_AUDIO_FORMAT_S16:
        equ->history_size = history_size_gint16;
        equ->process = gst_iir_equ_process_gint16;
        break;
    case GST_AUDIO_FORMAT_F32:
        equ->history_size = history_size_gfloat;
        equ->process = gst_iir_equ_process_gfloat;
        break;
    case GST_AUDIO_FORMAT_F64:
        equ->history_size = history_size_gdouble;
        equ->process = gst_iir_equ_process_gdouble;
        break;
    default:
        return FALSE;
    }

    alloc_history (equ, info);
    return TRUE;
}
static void
gst_iir_equalizer_nbands_init (GstIirEqualizerNBands * equ_n)
{
  GstIirEqualizer *equ = GST_IIR_EQUALIZER (equ_n);

  gst_iir_equalizer_compute_frequencies (equ, 10);
}
static GstFlowReturn
gst_iir_equalizer_transform_ip (GstBaseTransform * btrans, GstBuffer * buf)
{
  GstAudioFilter *filter = GST_AUDIO_FILTER (btrans);

  GstIirEqualizer *equ = GST_IIR_EQUALIZER (btrans);

  GstClockTime timestamp;

  if (G_UNLIKELY (filter->format.channels < 1 || equ->process == NULL))
    return GST_FLOW_NOT_NEGOTIATED;

  if (equ->need_new_coefficients) {
    update_coefficients (equ);
    set_passthrough (equ);
  }

  if (gst_base_transform_is_passthrough (btrans))
    return GST_FLOW_OK;

  timestamp = GST_BUFFER_TIMESTAMP (buf);
  timestamp =
      gst_segment_to_stream_time (&btrans->segment, GST_FORMAT_TIME, timestamp);

  if (GST_CLOCK_TIME_IS_VALID (timestamp))
    gst_object_sync_values (G_OBJECT (equ), timestamp);

  equ->process (equ, GST_BUFFER_DATA (buf), GST_BUFFER_SIZE (buf),
      filter->format.channels);

  return GST_FLOW_OK;
}
static void
gst_iir_equalizer_3bands_init (GstIirEqualizer3Bands * equ_n,
    GstIirEqualizer3BandsClass * g_class)
{
  GstIirEqualizer *equ = GST_IIR_EQUALIZER (equ_n);

  gst_iir_equalizer_compute_frequencies (equ, 3);
}
示例#5
0
static guint
gst_iir_equalizer_child_proxy_get_children_count (GstChildProxy * child_proxy)
{
  GstIirEqualizer *equ = GST_IIR_EQUALIZER (child_proxy);

  GST_LOG ("we have %d children", equ->freq_band_count);
  return equ->freq_band_count;
}
/* child proxy iface */
static GstObject *
gst_iir_equalizer_child_proxy_get_child_by_index (GstChildProxy * child_proxy,
    guint index)
{
  GstIirEqualizer *equ = GST_IIR_EQUALIZER (child_proxy);

  g_return_val_if_fail (index < equ->freq_band_count, NULL);

  GST_LOG ("return child[%d] '%s'", index, GST_OBJECT_NAME (equ->bands[index]));
  return (gst_object_ref (equ->bands[index]));
}
示例#7
0
static GstFlowReturn
gst_iir_equalizer_transform_ip (GstBaseTransform * btrans, GstBuffer * buf)
{
    GstAudioFilter *filter = GST_AUDIO_FILTER (btrans);
    GstIirEqualizer *equ = GST_IIR_EQUALIZER (btrans);
    GstClockTime timestamp;
    GstMapInfo map;
    gint channels = GST_AUDIO_FILTER_CHANNELS (filter);
    gboolean need_new_coefficients;

    if (G_UNLIKELY (channels < 1 || equ->process == NULL))
        return GST_FLOW_NOT_NEGOTIATED;

    BANDS_LOCK (equ);
    need_new_coefficients = equ->need_new_coefficients;
    BANDS_UNLOCK (equ);

    if (!need_new_coefficients && gst_base_transform_is_passthrough (btrans))
        return GST_FLOW_OK;

    timestamp = GST_BUFFER_TIMESTAMP (buf);
    timestamp =
        gst_segment_to_stream_time (&btrans->segment, GST_FORMAT_TIME, timestamp);

    if (GST_CLOCK_TIME_IS_VALID (timestamp)) {
        GstIirEqualizerBand **filters = equ->bands;
        guint f, nf = equ->freq_band_count;

        gst_object_sync_values (GST_OBJECT (equ), timestamp);

        /* sync values for bands too */
        /* FIXME: iterating equ->bands is not thread-safe here */
        for (f = 0; f < nf; f++) {
            gst_object_sync_values (GST_OBJECT (filters[f]), timestamp);
        }
    }

    BANDS_LOCK (equ);
    if (need_new_coefficients) {
        update_coefficients (equ);
        set_passthrough (equ);
    }
    BANDS_UNLOCK (equ);

    gst_buffer_map (buf, &map, GST_MAP_READWRITE);
    equ->process (equ, map.data, map.size, channels);
    gst_buffer_unmap (buf, &map);

    return GST_FLOW_OK;
}
static void
gst_iir_equalizer_nbands_get_property (GObject * object, guint prop_id,
    GValue * value, GParamSpec * pspec)
{
  GstIirEqualizer *equ = GST_IIR_EQUALIZER (object);

  switch (prop_id) {
    case PROP_NUM_BANDS:
      g_value_set_uint (value, equ->freq_band_count);
      break;
    default:
      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
      break;
  }
}
示例#9
0
/* child proxy iface */
static GstObject *
gst_iir_equalizer_child_proxy_get_child_by_index (GstChildProxy * child_proxy,
    guint index)
{
  GstIirEqualizer *equ = GST_IIR_EQUALIZER (child_proxy);
  GstObject *ret;

  BANDS_LOCK (equ);
  if (G_UNLIKELY (index >= equ->freq_band_count)) {
    BANDS_UNLOCK (equ);
    g_return_val_if_fail (index < equ->freq_band_count, NULL);
  }

  ret = gst_object_ref (equ->bands[index]);
  BANDS_UNLOCK (equ);

  GST_LOG_OBJECT (equ, "return child[%d] %" GST_PTR_FORMAT, index, ret);
  return ret;
}
static void
gst_iir_equalizer_finalize (GObject * object)
{
  GstIirEqualizer *equ = GST_IIR_EQUALIZER (object);

  gint i;

  for (i = 0; i < equ->freq_band_count; i++) {
    if (equ->bands[i])
      gst_object_unparent (GST_OBJECT (equ->bands[i]));
    equ->bands[i] = NULL;
  }
  equ->freq_band_count = 0;

  g_free (equ->bands);
  g_free (equ->history);

  G_OBJECT_CLASS (parent_class)->finalize (object);
}
static void
gst_iir_equalizer_3bands_get_property (GObject * object, guint prop_id,
    GValue * value, GParamSpec * pspec)
{
  GstIirEqualizer *equ = GST_IIR_EQUALIZER (object);

  switch (prop_id) {
    case ARG_BAND0:
      gst_child_proxy_get_property (GST_OBJECT (equ), "band0::gain", value);
      break;
    case ARG_BAND1:
      gst_child_proxy_get_property (GST_OBJECT (equ), "band1::gain", value);
      break;
    case ARG_BAND2:
      gst_child_proxy_get_property (GST_OBJECT (equ), "band2::gain", value);
      break;
    default:
      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
      break;
  }
}
示例#12
0
static gboolean
gst_iir_equalizer_setup (GstAudioFilter * audio, GstRingBufferSpec * fmt)
{
  GstIirEqualizer *equ = GST_IIR_EQUALIZER (audio);

  switch (fmt->type) {
    case GST_BUFTYPE_LINEAR:
      switch (fmt->width) {
        case 16:
          equ->history_size = history_size_gint16;
          equ->process = gst_iir_equ_process_gint16;
          break;
        default:
          return FALSE;
      }
      break;
    case GST_BUFTYPE_FLOAT:
      switch (fmt->width) {
        case 32:
          equ->history_size = history_size_gfloat;
          equ->process = gst_iir_equ_process_gfloat;
          break;
        case 64:
          equ->history_size = history_size_gdouble;
          equ->process = gst_iir_equ_process_gdouble;
          break;
        default:
          return FALSE;
      }
      break;
    default:
      return FALSE;
  }

  alloc_history (equ);
  return TRUE;
}
示例#13
0
static void
gst_iir_equalizer_band_set_property (GObject * object, guint prop_id,
    const GValue * value, GParamSpec * pspec)
{
  GstIirEqualizerBand *band = GST_IIR_EQUALIZER_BAND (object);
  GstIirEqualizer *equ =
      GST_IIR_EQUALIZER (gst_object_get_parent (GST_OBJECT (band)));

  switch (prop_id) {
    case PROP_GAIN:{
      gdouble gain;

      gain = g_value_get_double (value);
      GST_DEBUG_OBJECT (band, "gain = %lf -> %lf", band->gain, gain);
      if (gain != band->gain) {
        BANDS_LOCK (equ);
        equ->need_new_coefficients = TRUE;
        band->gain = gain;
        BANDS_UNLOCK (equ);
        GST_DEBUG_OBJECT (band, "changed gain = %lf ", band->gain);
      }
      break;
    }
    case PROP_FREQ:{
      gdouble freq;

      freq = g_value_get_double (value);
      GST_DEBUG_OBJECT (band, "freq = %lf -> %lf", band->freq, freq);
      if (freq != band->freq) {
        BANDS_LOCK (equ);
        equ->need_new_coefficients = TRUE;
        band->freq = freq;
        BANDS_UNLOCK (equ);
        GST_DEBUG_OBJECT (band, "changed freq = %lf ", band->freq);
      }
      break;
    }
    case PROP_BANDWIDTH:{
      gdouble width;

      width = g_value_get_double (value);
      GST_DEBUG_OBJECT (band, "width = %lf -> %lf", band->width, width);
      if (width != band->width) {
        BANDS_LOCK (equ);
        equ->need_new_coefficients = TRUE;
        band->width = width;
        BANDS_UNLOCK (equ);
        GST_DEBUG_OBJECT (band, "changed width = %lf ", band->width);
      }
      break;
    }
    case PROP_TYPE:{
      GstIirEqualizerBandType type;

      type = g_value_get_enum (value);
      GST_DEBUG_OBJECT (band, "type = %d -> %d", band->type, type);
      if (type != band->type) {
        BANDS_LOCK (equ);
        equ->need_new_coefficients = TRUE;
        band->type = type;
        BANDS_UNLOCK (equ);
        GST_DEBUG_OBJECT (band, "changed type = %d ", band->type);
      }
      break;
    }
    default:
      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
      break;
  }

  gst_object_unref (equ);
}
示例#14
0
static void
gst_iir_equalizer_band_set_property (GObject * object, guint prop_id,
    const GValue * value, GParamSpec * pspec)
{
  GstIirEqualizerBand *band = GST_IIR_EQUALIZER_BAND (object);
  GstIirEqualizer *equ =
      GST_IIR_EQUALIZER (gst_object_get_parent (GST_OBJECT (band)));

  switch (prop_id) {
    case PROP_GAIN:{
      gdouble gain;

      gain = g_value_get_double (value);
      GST_DEBUG_OBJECT (band, "gain = %lf -> %lf", band->gain, gain);
      if (gain != band->gain) {
        BANDS_LOCK (equ);
        equ->need_new_coefficients = TRUE;
        band->gain = gain;
        set_passthrough (equ);
        BANDS_UNLOCK (equ);
        GST_DEBUG_OBJECT (band, "changed gain = %lf ", band->gain);
      }
      break;
    }
    case PROP_FREQ:{
      gdouble freq;

      freq = g_value_get_double (value);
      GST_DEBUG_OBJECT (band, "freq = %lf -> %lf", band->freq, freq);
      if (freq != band->freq) {
        BANDS_LOCK (equ);
        equ->need_new_coefficients = TRUE;
        band->freq = freq;
        BANDS_UNLOCK (equ);
        GST_DEBUG_OBJECT (band, "changed freq = %lf ", band->freq);
      }
      break;
    }
    case PROP_BANDWIDTH:{
      gdouble width;

      width = g_value_get_double (value);
      GST_DEBUG_OBJECT (band, "width = %lf -> %lf", band->width, width);
      if (width != band->width) {
        BANDS_LOCK (equ);
        equ->need_new_coefficients = TRUE;
        band->width = width;
        BANDS_UNLOCK (equ);
        GST_DEBUG_OBJECT (band, "changed width = %lf ", band->width);
      }
      break;
    }
    case PROP_TYPE:{
      GstIirEqualizerBandType type;

      type = g_value_get_enum (value);
      GST_DEBUG_OBJECT (band, "type = %d -> %d", band->type, type);
      if (type != band->type) {
        BANDS_LOCK (equ);
        equ->need_new_coefficients = TRUE;
        band->type = type;
        BANDS_UNLOCK (equ);
        GST_DEBUG_OBJECT (band, "changed type = %d ", band->type);
      }
      break;
    }
    default:
      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
      break;
  }

#ifdef GSTREAMER_LITE
  // We need to update coefficients and disable passthrough
  // if needed, otherwise after we disable passthrough equalizer will not
  // get re-enabled.
//  BANDS_LOCK (equ);
//  if (equ->need_new_coefficients) {
//    update_coefficients (equ);
//    set_passthrough (equ);
//  }
//  BANDS_UNLOCK (equ);
#endif // GSTREAMER_LITE

  gst_object_unref (equ);
}