Release 1.1.4
[platform/upstream/gst-plugins-good.git] / gst / audiofx / audioecho.c
index 38cafd2..60220f0 100644 (file)
@@ -14,8 +14,8 @@
  *
  * You should have received a copy of the GNU Library General Public
  * License along with this library; if not, write to the
- * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
- * Boston, MA 02111-1307, USA.
+ * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
  */
 
 /**
@@ -36,8 +36,8 @@
  * <refsect2>
  * <title>Example launch line</title>
  * |[
- * gst-launch filesrc location="melo1.ogg" ! audioconvert ! audioecho delay=500000000 intensity=0.6 feedback=0.4 ! audioconvert ! autoaudiosink
- * gst-launch filesrc location="melo1.ogg" ! decodebin ! audioconvert ! audioecho delay=50000000 intensity=0.6 feedback=0.4 ! audioconvert ! autoaudiosink
+ * gst-launch-1.0 filesrc location="melo1.ogg" ! audioconvert ! audioecho delay=500000000 intensity=0.6 feedback=0.4 ! audioconvert ! autoaudiosink
+ * gst-launch-1.0 filesrc location="melo1.ogg" ! decodebin ! audioconvert ! audioecho delay=50000000 intensity=0.6 feedback=0.4 ! audioconvert ! autoaudiosink
  * ]|
  * </refsect2>
  */
@@ -69,7 +69,8 @@ enum
     "audio/x-raw,"                                                 \
     " format=(string) {"GST_AUDIO_NE(F32)","GST_AUDIO_NE(F64)"}, " \
     " rate=(int)[1,MAX],"                                          \
-    " channels=(int)[1,MAX]"
+    " channels=(int)[1,MAX],"                                      \
+    " layout=(string) interleaved"
 
 #define gst_audio_echo_parent_class parent_class
 G_DEFINE_TYPE (GstAudioEcho, gst_audio_echo, GST_TYPE_AUDIO_FILTER);
@@ -135,7 +136,7 @@ gst_audio_echo_class_init (GstAudioEchoClass * klass)
           0.0, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS
           | GST_PARAM_CONTROLLABLE));
 
-  gst_element_class_set_details_simple (gstelement_class, "Audio echo",
+  gst_element_class_set_static_metadata (gstelement_class, "Audio echo",
       "Filter/Effect/Audio",
       "Adds an echo or reverb effect to an audio stream",
       "Sebastian Dröge <sebastian.droege@collabora.co.uk>");
@@ -159,6 +160,8 @@ gst_audio_echo_init (GstAudioEcho * self)
   self->intensity = 0.0;
   self->feedback = 0.0;
 
+  g_mutex_init (&self->lock);
+
   gst_base_transform_set_in_place (GST_BASE_TRANSFORM (self), TRUE);
 }
 
@@ -170,6 +173,8 @@ gst_audio_echo_finalize (GObject * object)
   g_free (self->buffer);
   self->buffer = NULL;
 
+  g_mutex_clear (&self->lock);
+
   G_OBJECT_CLASS (parent_class)->finalize (object);
 }
 
@@ -182,8 +187,9 @@ gst_audio_echo_set_property (GObject * object, guint prop_id,
   switch (prop_id) {
     case PROP_DELAY:{
       guint64 max_delay, delay;
+      guint rate;
 
-      GST_BASE_TRANSFORM_LOCK (self);
+      g_mutex_lock (&self->lock);
       delay = g_value_get_uint64 (value);
       max_delay = self->max_delay;
 
@@ -196,13 +202,18 @@ gst_audio_echo_set_property (GObject * object, guint prop_id,
         self->delay = delay;
         self->max_delay = MAX (delay, max_delay);
       }
-      GST_BASE_TRANSFORM_UNLOCK (self);
-    }
+      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, delay;
 
-      GST_BASE_TRANSFORM_LOCK (self);
+      g_mutex_lock (&self->lock);
       max_delay = g_value_get_uint64 (value);
       delay = self->delay;
 
@@ -213,21 +224,21 @@ gst_audio_echo_set_property (GObject * object, guint prop_id,
         self->delay = delay;
         self->max_delay = max_delay;
       }
-      GST_BASE_TRANSFORM_UNLOCK (self);
-    }
+      g_mutex_unlock (&self->lock);
       break;
+    }
     case PROP_INTENSITY:{
-      GST_BASE_TRANSFORM_LOCK (self);
+      g_mutex_lock (&self->lock);
       self->intensity = g_value_get_float (value);
-      GST_BASE_TRANSFORM_UNLOCK (self);
-    }
+      g_mutex_unlock (&self->lock);
       break;
+    }
     case PROP_FEEDBACK:{
-      GST_BASE_TRANSFORM_LOCK (self);
+      g_mutex_lock (&self->lock);
       self->feedback = g_value_get_float (value);
-      GST_BASE_TRANSFORM_UNLOCK (self);
-    }
+      g_mutex_unlock (&self->lock);
       break;
+    }
     default:
       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
       break;
@@ -242,24 +253,24 @@ gst_audio_echo_get_property (GObject * object, guint prop_id,
 
   switch (prop_id) {
     case PROP_DELAY:
-      GST_BASE_TRANSFORM_LOCK (self);
+      g_mutex_lock (&self->lock);
       g_value_set_uint64 (value, self->delay);
-      GST_BASE_TRANSFORM_UNLOCK (self);
+      g_mutex_unlock (&self->lock);
       break;
     case PROP_MAX_DELAY:
-      GST_BASE_TRANSFORM_LOCK (self);
+      g_mutex_lock (&self->lock);
       g_value_set_uint64 (value, self->max_delay);
-      GST_BASE_TRANSFORM_UNLOCK (self);
+      g_mutex_unlock (&self->lock);
       break;
     case PROP_INTENSITY:
-      GST_BASE_TRANSFORM_LOCK (self);
+      g_mutex_lock (&self->lock);
       g_value_set_float (value, self->intensity);
-      GST_BASE_TRANSFORM_UNLOCK (self);
+      g_mutex_unlock (&self->lock);
       break;
     case PROP_FEEDBACK:
-      GST_BASE_TRANSFORM_LOCK (self);
+      g_mutex_lock (&self->lock);
       g_value_set_float (value, self->feedback);
-      GST_BASE_TRANSFORM_UNLOCK (self);
+      g_mutex_unlock (&self->lock);
       break;
     default:
       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
@@ -358,9 +369,9 @@ gst_audio_echo_transform_ip (GstBaseTransform * base, GstBuffer * buf)
   GstAudioEcho *self = GST_AUDIO_ECHO (base);
   guint num_samples;
   GstClockTime timestamp, stream_time;
-  guint8 *data;
-  gsize size;
+  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);
@@ -387,17 +398,19 @@ gst_audio_echo_transform_ip (GstBaseTransform * base, GstBuffer * buf)
     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;
     }
   }
 
-  data = gst_buffer_map (buf, &size, NULL, GST_MAP_READWRITE);
-  num_samples = size / GST_AUDIO_FILTER_BPS (self);
+  gst_buffer_map (buf, &map, GST_MAP_READWRITE);
+  num_samples = map.size / GST_AUDIO_FILTER_BPS (self);
 
-  self->process (self, data, num_samples);
+  self->process (self, map.data, num_samples);
 
-  gst_buffer_unmap (buf, data, size);
+  gst_buffer_unmap (buf, &map);
+  g_mutex_unlock (&self->lock);
 
   return GST_FLOW_OK;
 }