static gboolean
gst_freeverb_set_caps (GstBaseTransform * base, GstCaps * incaps,
                       GstCaps * outcaps)
{
    GstFreeverb *filter = GST_FREEVERB (base);
    GstAudioInfo info;

    /*GST_INFO ("incaps are %" GST_PTR_FORMAT, incaps); */
    if (!gst_audio_info_from_caps (&info, incaps))
        goto no_format;

    GST_DEBUG ("try to process %d input with %d channels",
               GST_AUDIO_INFO_FORMAT (&info), GST_AUDIO_INFO_CHANNELS (&info));

    if (!gst_freeverb_set_process_function (filter, &info))
        goto no_format;

    filter->info = info;

    gst_freeverb_init_rev_model (filter);
    filter->drained = FALSE;
    GST_INFO_OBJECT (base, "model configured");

    return TRUE;

no_format:
    {
        GST_DEBUG ("invalid caps");
        return FALSE;
    }
}
示例#2
0
static gboolean
gst_freeverb_set_caps (GstBaseTransform * base, GstCaps * incaps,
    GstCaps * outcaps)
{
  GstFreeverb *filter = GST_FREEVERB (base);
  const GstStructure *structure;
  gboolean ret;
  gint width, rate;
  const gchar *fmt;

  /*GST_INFO ("incaps are %" GST_PTR_FORMAT, incaps); */

  structure = gst_caps_get_structure (incaps, 0);
  ret = gst_structure_get_int (structure, "channels", &filter->channels);
  if (!ret)
    goto no_channels;

  ret = gst_structure_get_int (structure, "width", &width);
  if (!ret)
    goto no_width;
  filter->width = width / 8;

  ret = gst_structure_get_int (structure, "rate", &rate);
  if (!ret)
    goto no_rate;
  filter->rate = rate;

  fmt = gst_structure_get_name (structure);
  if (!strcmp (fmt, "audio/x-raw-int"))
    filter->format_float = FALSE;
  else
    filter->format_float = TRUE;

  GST_DEBUG_OBJECT (filter, "try to process %s input_1 with %d channels", fmt,
      filter->channels);

  ret = gst_freeverb_set_process_function (filter);
  if (!ret)
    GST_WARNING_OBJECT (filter, "can't process input_1 with %d channels",
        filter->channels);

  gst_freeverb_init_rev_model (filter);
  filter->drained = FALSE;
  GST_INFO_OBJECT (base, "model configured");

  return ret;

no_channels:
  GST_DEBUG_OBJECT (filter, "no channels in caps");
  return ret;
no_width:
  GST_DEBUG_OBJECT (filter, "no width in caps");
  return ret;
no_rate:
  GST_DEBUG_OBJECT (filter, "no rate in caps");
  return ret;
}
示例#3
0
static void
gst_freeverb_finalize (GObject * object)
{
  GstFreeverb *filter = GST_FREEVERB (object);

  freeverb_revmodel_free (filter);

  G_OBJECT_CLASS (parent_class)->finalize (object);
}
/* this function does the actual processing
 */
static GstFlowReturn
gst_freeverb_transform (GstBaseTransform * base, GstBuffer * inbuf,
                        GstBuffer * outbuf)
{
    GstFreeverb *filter = GST_FREEVERB (base);
    guint num_samples;
    GstClockTime timestamp;
    GstMapInfo inmap, outmap;

    timestamp = GST_BUFFER_TIMESTAMP (inbuf);
    timestamp =
        gst_segment_to_stream_time (&base->segment, GST_FORMAT_TIME, timestamp);

    gst_buffer_map (inbuf, &inmap, GST_MAP_READ);
    gst_buffer_map (outbuf, &outmap, GST_MAP_WRITE);
    num_samples = outmap.size / (2 * GST_AUDIO_INFO_BPS (&filter->info));

    GST_DEBUG_OBJECT (filter, "processing %u samples at %" GST_TIME_FORMAT,
                      num_samples, GST_TIME_ARGS (timestamp));

    if (GST_CLOCK_TIME_IS_VALID (timestamp))
        gst_object_sync_values (GST_OBJECT (filter), timestamp);

    if (G_UNLIKELY (GST_BUFFER_FLAG_IS_SET (inbuf, GST_BUFFER_FLAG_DISCONT))) {
        filter->drained = FALSE;
    }
    if (G_UNLIKELY (GST_BUFFER_FLAG_IS_SET (inbuf, GST_BUFFER_FLAG_GAP))) {
        if (filter->drained) {
            memset (outmap.data, 0, outmap.size);
        }
    } else {
        filter->drained = FALSE;
    }

    if (!filter->drained) {
        filter->drained =
            filter->process (filter, inmap.data, outmap.data, num_samples);
    }

    if (filter->drained) {
        GST_BUFFER_FLAG_SET (outbuf, GST_BUFFER_FLAG_GAP);
    }

    gst_buffer_unmap (inbuf, &inmap);
    gst_buffer_unmap (outbuf, &outmap);

    return GST_FLOW_OK;
}
示例#5
0
static void
gst_freeverb_set_property (GObject * object, guint prop_id,
    const GValue * value, GParamSpec * pspec)
{
  GstFreeverb *filter = GST_FREEVERB (object);
  GstFreeverbPrivate *priv = filter->priv;
  gint i;

  switch (prop_id) {
    case PROP_ROOM_SIZE:
      filter->room_size = g_value_get_float (value);
      priv->roomsize = (filter->room_size * scaleroom) + offsetroom;
      for (i = 0; i < numcombs; i++) {
        freeverb_comb_setfeedback (&priv->combL[i], priv->roomsize);
        freeverb_comb_setfeedback (&priv->combR[i], priv->roomsize);
      }
      break;
    case PROP_DAMPING:
      filter->damping = g_value_get_float (value);
      priv->damp = filter->damping * scaledamp;
      for (i = 0; i < numcombs; i++) {
        freeverb_comb_setdamp (&priv->combL[i], priv->damp);
        freeverb_comb_setdamp (&priv->combR[i], priv->damp);
      }
      break;
    case PROP_PAN_WIDTH:
      filter->pan_width = g_value_get_float (value);
      priv->width = filter->pan_width;
      priv->wet1 = priv->wet * (priv->width / 2.0f + 0.5f);
      priv->wet2 = priv->wet * ((1.0f - priv->width) / 2.0f);
      break;
    case PROP_LEVEL:
      filter->level = g_value_get_float (value);
      priv->wet = filter->level * scalewet;
      priv->dry = (1.0 - filter->level) * scaledry;
      priv->wet1 = priv->wet * (priv->width / 2.0f + 0.5f);
      priv->wet2 = priv->wet * ((1.0f - priv->width) / 2.0f);
      break;
    default:
      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
      break;
  }
}
示例#6
0
/* this function does the actual processing
 */
static GstFlowReturn
gst_freeverb_transform (GstBaseTransform * base, GstBuffer * inbuf,
    GstBuffer * outbuf)
{
  GstFreeverb *filter = GST_FREEVERB (base);
  guint num_samples = GST_BUFFER_SIZE (outbuf) / (2 * filter->width);
  GstClockTime timestamp;

  timestamp = GST_BUFFER_TIMESTAMP (inbuf);
  timestamp =
      gst_segment_to_stream_time (&base->segment, GST_FORMAT_TIME, timestamp);

  GST_DEBUG_OBJECT (filter, "processing %u samples at %" GST_TIME_FORMAT,
      num_samples, GST_TIME_ARGS (timestamp));

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

  if (G_UNLIKELY (GST_BUFFER_FLAG_IS_SET (inbuf, GST_BUFFER_FLAG_DISCONT))) {
    filter->drained = FALSE;
  }
  if (G_UNLIKELY (GST_BUFFER_FLAG_IS_SET (inbuf, GST_BUFFER_FLAG_GAP))) {
    if (filter->drained) {
      GST_BUFFER_FLAG_SET (outbuf, GST_BUFFER_FLAG_GAP);
      memset (GST_BUFFER_DATA (outbuf), 0, GST_BUFFER_SIZE (outbuf));
      return GST_FLOW_OK;
    }
  } else {
    filter->drained = FALSE;
  }

  filter->drained = filter->process (filter, GST_BUFFER_DATA (inbuf),
      GST_BUFFER_DATA (outbuf), num_samples);

  if (filter->drained) {
    GST_BUFFER_FLAG_SET (outbuf, GST_BUFFER_FLAG_GAP);
  }

  return GST_FLOW_OK;
}
示例#7
0
static void
gst_freeverb_get_property (GObject * object, guint prop_id,
    GValue * value, GParamSpec * pspec)
{
  GstFreeverb *filter = GST_FREEVERB (object);

  switch (prop_id) {
    case PROP_ROOM_SIZE:
      g_value_set_float (value, filter->room_size);
      break;
    case PROP_DAMPING:
      g_value_set_float (value, filter->damping);
      break;
    case PROP_PAN_WIDTH:
      g_value_set_float (value, filter->pan_width);
      break;
    case PROP_LEVEL:
      g_value_set_float (value, filter->level);
      break;
    default:
      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
      break;
  }
}