Beispiel #1
0
static void
gst_audio_echo_get_property (GObject * object, guint prop_id,
    GValue * value, GParamSpec * pspec)
{
  GstAudioEcho *self = GST_AUDIO_ECHO (object);

  switch (prop_id) {
    case PROP_DELAY:
      GST_BASE_TRANSFORM_LOCK (self);
      g_value_set_uint64 (value, self->delay);
      GST_BASE_TRANSFORM_UNLOCK (self);
      break;
    case PROP_MAX_DELAY:
      GST_BASE_TRANSFORM_LOCK (self);
      g_value_set_uint64 (value, self->max_delay);
      GST_BASE_TRANSFORM_UNLOCK (self);
      break;
    case PROP_INTENSITY:
      GST_BASE_TRANSFORM_LOCK (self);
      g_value_set_float (value, self->intensity);
      GST_BASE_TRANSFORM_UNLOCK (self);
      break;
    case PROP_FEEDBACK:
      GST_BASE_TRANSFORM_LOCK (self);
      g_value_set_float (value, self->feedback);
      GST_BASE_TRANSFORM_UNLOCK (self);
      break;
    default:
      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
      break;
  }
}
Beispiel #2
0
static void
gst_audio_echo_set_property (GObject * object, guint prop_id,
    const GValue * value, GParamSpec * pspec)
{
  GstAudioEcho *self = GST_AUDIO_ECHO (object);

  switch (prop_id) {
    case PROP_DELAY:{
      guint64 max_delay, delay;

      GST_BASE_TRANSFORM_LOCK (self);
      delay = g_value_get_uint64 (value);
      max_delay = self->max_delay;

      if (delay > max_delay && GST_STATE (self) > GST_STATE_READY) {
        GST_WARNING_OBJECT (self, "New delay (%" GST_TIME_FORMAT ") "
            "is larger than maximum delay (%" GST_TIME_FORMAT ")",
            GST_TIME_ARGS (delay), GST_TIME_ARGS (max_delay));
        self->delay = max_delay;
      } else {
        self->delay = delay;
        self->max_delay = MAX (delay, max_delay);
      }
      GST_BASE_TRANSFORM_UNLOCK (self);
    }
      break;
    case PROP_MAX_DELAY:{
      guint64 max_delay, delay;

      GST_BASE_TRANSFORM_LOCK (self);
      max_delay = g_value_get_uint64 (value);
      delay = self->delay;

      if (GST_STATE (self) > GST_STATE_READY) {
        GST_ERROR_OBJECT (self, "Can't change maximum delay in"
            " PLAYING or PAUSED state");
      } else {
        self->delay = delay;
        self->max_delay = max_delay;
      }
      GST_BASE_TRANSFORM_UNLOCK (self);
    }
      break;
    case PROP_INTENSITY:{
      GST_BASE_TRANSFORM_LOCK (self);
      self->intensity = g_value_get_float (value);
      GST_BASE_TRANSFORM_UNLOCK (self);
    }
      break;
    case PROP_FEEDBACK:{
      GST_BASE_TRANSFORM_LOCK (self);
      self->feedback = g_value_get_float (value);
      GST_BASE_TRANSFORM_UNLOCK (self);
    }
      break;
    default:
      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
      break;
  }
}
static gboolean
gst_audio_echo_setup (GstAudioFilter * base, const GstAudioInfo * info)
{
  GstAudioEcho *self = GST_AUDIO_ECHO (base);
  gboolean ret = TRUE;

  switch (GST_AUDIO_INFO_FORMAT (info)) {
    case GST_AUDIO_FORMAT_F32:
      self->process = (GstAudioEchoProcessFunc)
          gst_audio_echo_transform_float;
      break;
    case GST_AUDIO_FORMAT_F64:
      self->process = (GstAudioEchoProcessFunc)
          gst_audio_echo_transform_double;
      break;
    default:
      ret = FALSE;
      break;
  }

  g_free (self->buffer);
  self->buffer = NULL;
  self->buffer_pos = 0;
  self->buffer_size = 0;
  self->buffer_size_frames = 0;

  return ret;
}
Beispiel #4
0
static void
gst_audio_echo_finalize (GObject * object)
{
  GstAudioEcho *self = GST_AUDIO_ECHO (object);

  g_free (self->buffer);
  self->buffer = NULL;

  G_OBJECT_CLASS (parent_class)->finalize (object);
}
Beispiel #5
0
static gboolean
gst_audio_echo_stop (GstBaseTransform * base)
{
  GstAudioEcho *self = GST_AUDIO_ECHO (base);

  g_free (self->buffer);
  self->buffer = NULL;
  self->buffer_pos = 0;
  self->buffer_size = 0;
  self->buffer_size_frames = 0;

  return TRUE;
}
/* GstBaseTransform vmethod implementations */
static GstFlowReturn
gst_audio_echo_transform_ip (GstBaseTransform * base, GstBuffer * buf)
{
  GstAudioEcho *self = GST_AUDIO_ECHO (base);
  guint num_samples;
  GstClockTime timestamp, stream_time;
  GstMapInfo map;

  g_mutex_lock (&self->lock);
  timestamp = GST_BUFFER_TIMESTAMP (buf);
  stream_time =
      gst_segment_to_stream_time (&base->segment, GST_FORMAT_TIME, timestamp);

  GST_DEBUG_OBJECT (self, "sync to %" GST_TIME_FORMAT,
      GST_TIME_ARGS (timestamp));

  if (GST_CLOCK_TIME_IS_VALID (stream_time))
    gst_object_sync_values (GST_OBJECT (self), stream_time);

  if (self->buffer == NULL) {
    guint bpf, rate;

    bpf = GST_AUDIO_FILTER_BPF (self);
    rate = GST_AUDIO_FILTER_RATE (self);

    self->delay_frames =
        MAX (gst_util_uint64_scale (self->delay, rate, GST_SECOND), 1);
    self->buffer_size_frames =
        MAX (gst_util_uint64_scale (self->max_delay, rate, GST_SECOND), 1);

    self->buffer_size = self->buffer_size_frames * bpf;
    self->buffer = g_try_malloc0 (self->buffer_size);
    self->buffer_pos = 0;

    if (self->buffer == NULL) {
      g_mutex_unlock (&self->lock);
      GST_ERROR_OBJECT (self, "Failed to allocate %u bytes", self->buffer_size);
      return GST_FLOW_ERROR;
    }
  }

  gst_buffer_map (buf, &map, GST_MAP_READWRITE);
  num_samples = map.size / GST_AUDIO_FILTER_BPS (self);

  self->process (self, map.data, num_samples);

  gst_buffer_unmap (buf, &map);
  g_mutex_unlock (&self->lock);

  return GST_FLOW_OK;
}
Beispiel #7
0
/* GstBaseTransform vmethod implementations */
static GstFlowReturn
gst_audio_echo_transform_ip (GstBaseTransform * base, GstBuffer * buf)
{
  GstAudioEcho *self = GST_AUDIO_ECHO (base);
  guint num_samples;
  GstClockTime timestamp, stream_time;

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

  GST_DEBUG_OBJECT (self, "sync to %" GST_TIME_FORMAT,
      GST_TIME_ARGS (timestamp));

  if (GST_CLOCK_TIME_IS_VALID (stream_time))
    gst_object_sync_values (G_OBJECT (self), stream_time);

  num_samples =
      GST_BUFFER_SIZE (buf) / (GST_AUDIO_FILTER (self)->format.width / 8);

  if (self->buffer == NULL) {
    guint width, rate, channels;

    width = GST_AUDIO_FILTER (self)->format.width / 8;
    rate = GST_AUDIO_FILTER (self)->format.rate;
    channels = GST_AUDIO_FILTER (self)->format.channels;

    self->delay_frames =
        MAX (gst_util_uint64_scale (self->delay, rate, GST_SECOND), 1);
    self->buffer_size_frames =
        MAX (gst_util_uint64_scale (self->max_delay, rate, GST_SECOND), 1);

    self->buffer_size = self->buffer_size_frames * width * channels;
    self->buffer = g_try_malloc0 (self->buffer_size);
    self->buffer_pos = 0;

    if (self->buffer == NULL) {
      GST_ERROR_OBJECT (self, "Failed to allocate %u bytes", self->buffer_size);
      return GST_FLOW_ERROR;
    }
  }

  self->process (self, GST_BUFFER_DATA (buf), num_samples);

  return GST_FLOW_OK;
}
Beispiel #8
0
static gboolean
gst_audio_echo_setup (GstAudioFilter * base, GstRingBufferSpec * format)
{
  GstAudioEcho *self = GST_AUDIO_ECHO (base);
  gboolean ret = TRUE;

  if (format->type == GST_BUFTYPE_FLOAT && format->width == 32)
    self->process = (GstAudioEchoProcessFunc)
        gst_audio_echo_transform_float;
  else if (format->type == GST_BUFTYPE_FLOAT && format->width == 64)
    self->process = (GstAudioEchoProcessFunc)
        gst_audio_echo_transform_double;
  else
    ret = FALSE;

  g_free (self->buffer);
  self->buffer = NULL;
  self->buffer_pos = 0;
  self->buffer_size = 0;
  self->buffer_size_frames = 0;

  return ret;
}
static void
gst_audio_echo_set_property (GObject * object, guint prop_id,
    const GValue * value, GParamSpec * pspec)
{
  GstAudioEcho *self = GST_AUDIO_ECHO (object);

  switch (prop_id) {
    case PROP_DELAY:{
      guint64 max_delay, delay;
      guint rate;

      g_mutex_lock (&self->lock);
      delay = g_value_get_uint64 (value);
      max_delay = self->max_delay;

      if (delay > max_delay && GST_STATE (self) > GST_STATE_READY) {
        GST_WARNING_OBJECT (self, "New delay (%" GST_TIME_FORMAT ") "
            "is larger than maximum delay (%" GST_TIME_FORMAT ")",
            GST_TIME_ARGS (delay), GST_TIME_ARGS (max_delay));
        self->delay = max_delay;
      } else {
        self->delay = delay;
        self->max_delay = MAX (delay, max_delay);
        if (delay > max_delay) {
          g_free (self->buffer);
          self->buffer = NULL;
        }
      }
      rate = GST_AUDIO_FILTER_RATE (self);
      if (rate > 0)
        self->delay_frames =
            MAX (gst_util_uint64_scale (self->delay, rate, GST_SECOND), 1);

      g_mutex_unlock (&self->lock);
      break;
    }
    case PROP_MAX_DELAY:{
      guint64 max_delay;

      g_mutex_lock (&self->lock);
      max_delay = g_value_get_uint64 (value);

      if (GST_STATE (self) > GST_STATE_READY) {
        GST_ERROR_OBJECT (self, "Can't change maximum delay in"
            " PLAYING or PAUSED state");
      } else {
        self->max_delay = max_delay;
        g_free (self->buffer);
        self->buffer = NULL;
      }
      g_mutex_unlock (&self->lock);
      break;
    }
    case PROP_INTENSITY:{
      g_mutex_lock (&self->lock);
      self->intensity = g_value_get_float (value);
      g_mutex_unlock (&self->lock);
      break;
    }
    case PROP_FEEDBACK:{
      g_mutex_lock (&self->lock);
      self->feedback = g_value_get_float (value);
      g_mutex_unlock (&self->lock);
      break;
    }
    default:
      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
      break;
  }
}