mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2025-01-28 10:08:17 +00:00
soundtouch: port to 0.11
This commit is contained in:
parent
29092cc3b8
commit
2eefdda3e4
3 changed files with 130 additions and 163 deletions
|
@ -323,7 +323,7 @@ GST_PLUGINS_NONPORTED=" aiff \
|
||||||
decklink fbdev linsys vcd \
|
decklink fbdev linsys vcd \
|
||||||
apexsink cdaudio cog dc1394 dirac directfb resindvd \
|
apexsink cdaudio cog dc1394 dirac directfb resindvd \
|
||||||
gsettings jasper ladspa mimic \
|
gsettings jasper ladspa mimic \
|
||||||
musepack musicbrainz nas neon ofa openal opencv rsvg sdl sndfile soundtouch spandsp spc timidity \
|
musepack musicbrainz nas neon ofa openal opencv rsvg sdl sndfile spandsp spc timidity \
|
||||||
directsound directdraw direct3d9 acm wininet \
|
directsound directdraw direct3d9 acm wininet \
|
||||||
wildmidi xvid lv2 teletextdec dvb sndio"
|
wildmidi xvid lv2 teletextdec dvb sndio"
|
||||||
AC_SUBST(GST_PLUGINS_NONPORTED)
|
AC_SUBST(GST_PLUGINS_NONPORTED)
|
||||||
|
|
|
@ -56,14 +56,13 @@ struct _GstBPMDetectPrivate
|
||||||
};
|
};
|
||||||
|
|
||||||
#define ALLOWED_CAPS \
|
#define ALLOWED_CAPS \
|
||||||
"audio/x-raw-float, " \
|
"audio/x-raw, " \
|
||||||
" width = (int) 32, " \
|
" format = (string) " GST_AUDIO_NE (F32) ", " \
|
||||||
" endianness = (int) BYTE_ORDER, " \
|
|
||||||
" rate = (int) [ 8000, MAX ], " \
|
" rate = (int) [ 8000, MAX ], " \
|
||||||
" channels = (int) [ 1, 2 ]"
|
" channels = (int) [ 1, 2 ]"
|
||||||
|
|
||||||
GST_BOILERPLATE (GstBPMDetect, gst_bpm_detect, GstAudioFilter,
|
#define gst_bpm_detect_parent_class parent_class
|
||||||
GST_TYPE_AUDIO_FILTER);
|
G_DEFINE_TYPE (GstBPMDetect, gst_bpm_detect, GST_TYPE_AUDIO_FILTER);
|
||||||
|
|
||||||
static void gst_bpm_detect_finalize (GObject * object);
|
static void gst_bpm_detect_finalize (GObject * object);
|
||||||
static gboolean gst_bpm_detect_stop (GstBaseTransform * trans);
|
static gboolean gst_bpm_detect_stop (GstBaseTransform * trans);
|
||||||
|
@ -72,28 +71,14 @@ static gboolean gst_bpm_detect_event (GstBaseTransform * trans,
|
||||||
static GstFlowReturn gst_bpm_detect_transform_ip (GstBaseTransform * trans,
|
static GstFlowReturn gst_bpm_detect_transform_ip (GstBaseTransform * trans,
|
||||||
GstBuffer * in);
|
GstBuffer * in);
|
||||||
static gboolean gst_bpm_detect_setup (GstAudioFilter * filter,
|
static gboolean gst_bpm_detect_setup (GstAudioFilter * filter,
|
||||||
GstRingBufferSpec * format);
|
const GstAudioInfo * info);
|
||||||
|
|
||||||
static void
|
|
||||||
gst_bpm_detect_base_init (gpointer g_class)
|
|
||||||
{
|
|
||||||
GstElementClass *element_class = GST_ELEMENT_CLASS (g_class);
|
|
||||||
GstCaps *caps;
|
|
||||||
|
|
||||||
gst_element_class_set_details_simple (element_class, "BPM Detector",
|
|
||||||
"Filter/Analyzer/Audio", "Detect the BPM of an audio stream",
|
|
||||||
"Sebastian Dröge <slomo@circular-chaos.org>");
|
|
||||||
|
|
||||||
caps = gst_caps_from_string (ALLOWED_CAPS);
|
|
||||||
gst_audio_filter_class_add_pad_templates (GST_AUDIO_FILTER_CLASS (g_class),
|
|
||||||
caps);
|
|
||||||
gst_caps_unref (caps);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
gst_bpm_detect_class_init (GstBPMDetectClass * klass)
|
gst_bpm_detect_class_init (GstBPMDetectClass * klass)
|
||||||
{
|
{
|
||||||
|
GstCaps *caps;
|
||||||
GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
|
GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
|
||||||
|
GstElementClass *element_class = GST_ELEMENT_CLASS (klass);
|
||||||
GstBaseTransformClass *trans_class = GST_BASE_TRANSFORM_CLASS (klass);
|
GstBaseTransformClass *trans_class = GST_BASE_TRANSFORM_CLASS (klass);
|
||||||
GstAudioFilterClass *filter_class = GST_AUDIO_FILTER_CLASS (klass);
|
GstAudioFilterClass *filter_class = GST_AUDIO_FILTER_CLASS (klass);
|
||||||
|
|
||||||
|
@ -102,8 +87,17 @@ gst_bpm_detect_class_init (GstBPMDetectClass * klass)
|
||||||
|
|
||||||
gobject_class->finalize = gst_bpm_detect_finalize;
|
gobject_class->finalize = gst_bpm_detect_finalize;
|
||||||
|
|
||||||
|
gst_element_class_set_details_simple (element_class, "BPM Detector",
|
||||||
|
"Filter/Analyzer/Audio", "Detect the BPM of an audio stream",
|
||||||
|
"Sebastian Dröge <slomo@circular-chaos.org>");
|
||||||
|
|
||||||
|
caps = gst_caps_from_string (ALLOWED_CAPS);
|
||||||
|
gst_audio_filter_class_add_pad_templates (GST_AUDIO_FILTER_CLASS (klass),
|
||||||
|
caps);
|
||||||
|
gst_caps_unref (caps);
|
||||||
|
|
||||||
trans_class->stop = GST_DEBUG_FUNCPTR (gst_bpm_detect_stop);
|
trans_class->stop = GST_DEBUG_FUNCPTR (gst_bpm_detect_stop);
|
||||||
trans_class->event = GST_DEBUG_FUNCPTR (gst_bpm_detect_event);
|
trans_class->sink_event = GST_DEBUG_FUNCPTR (gst_bpm_detect_event);
|
||||||
trans_class->transform_ip = GST_DEBUG_FUNCPTR (gst_bpm_detect_transform_ip);
|
trans_class->transform_ip = GST_DEBUG_FUNCPTR (gst_bpm_detect_transform_ip);
|
||||||
trans_class->passthrough_on_same_caps = TRUE;
|
trans_class->passthrough_on_same_caps = TRUE;
|
||||||
|
|
||||||
|
@ -113,7 +107,7 @@ gst_bpm_detect_class_init (GstBPMDetectClass * klass)
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
gst_bpm_detect_init (GstBPMDetect * bpm_detect, GstBPMDetectClass * g_class)
|
gst_bpm_detect_init (GstBPMDetect * bpm_detect)
|
||||||
{
|
{
|
||||||
bpm_detect->priv = G_TYPE_INSTANCE_GET_PRIVATE ((bpm_detect),
|
bpm_detect->priv = G_TYPE_INSTANCE_GET_PRIVATE ((bpm_detect),
|
||||||
GST_TYPE_BPM_DETECT, GstBPMDetectPrivate);
|
GST_TYPE_BPM_DETECT, GstBPMDetectPrivate);
|
||||||
|
@ -159,7 +153,7 @@ gst_bpm_detect_event (GstBaseTransform * trans, GstEvent * event)
|
||||||
switch (GST_EVENT_TYPE (event)) {
|
switch (GST_EVENT_TYPE (event)) {
|
||||||
case GST_EVENT_FLUSH_STOP:
|
case GST_EVENT_FLUSH_STOP:
|
||||||
case GST_EVENT_EOS:
|
case GST_EVENT_EOS:
|
||||||
case GST_EVENT_NEWSEGMENT:
|
case GST_EVENT_SEGMENT:
|
||||||
if (bpm_detect->priv->detect) {
|
if (bpm_detect->priv->detect) {
|
||||||
delete bpm_detect->priv->detect;
|
delete bpm_detect->priv->detect;
|
||||||
|
|
||||||
|
@ -175,7 +169,7 @@ gst_bpm_detect_event (GstBaseTransform * trans, GstEvent * event)
|
||||||
}
|
}
|
||||||
|
|
||||||
static gboolean
|
static gboolean
|
||||||
gst_bpm_detect_setup (GstAudioFilter * filter, GstRingBufferSpec * format)
|
gst_bpm_detect_setup (GstAudioFilter * filter, const GstAudioInfo * info)
|
||||||
{
|
{
|
||||||
GstBPMDetect *bpm_detect = GST_BPM_DETECT (filter);
|
GstBPMDetect *bpm_detect = GST_BPM_DETECT (filter);
|
||||||
|
|
||||||
|
@ -195,29 +189,33 @@ gst_bpm_detect_transform_ip (GstBaseTransform * trans, GstBuffer * in)
|
||||||
GstAudioFilter *filter = GST_AUDIO_FILTER (trans);
|
GstAudioFilter *filter = GST_AUDIO_FILTER (trans);
|
||||||
gint nsamples;
|
gint nsamples;
|
||||||
gfloat bpm;
|
gfloat bpm;
|
||||||
|
GstMapInfo info;
|
||||||
|
|
||||||
if (G_UNLIKELY (!bpm_detect->priv->detect)) {
|
if (G_UNLIKELY (!bpm_detect->priv->detect)) {
|
||||||
if (filter->format.channels == 0 || filter->format.rate == 0) {
|
if (GST_AUDIO_INFO_FORMAT (&filter->info) == GST_AUDIO_FORMAT_UNKNOWN) {
|
||||||
GST_ERROR_OBJECT (bpm_detect, "No channels or rate set yet");
|
GST_ERROR_OBJECT (bpm_detect, "No channels or rate set yet");
|
||||||
return GST_FLOW_ERROR;
|
return GST_FLOW_ERROR;
|
||||||
}
|
}
|
||||||
#ifdef HAVE_SOUNDTOUCH_1_4
|
#ifdef HAVE_SOUNDTOUCH_1_4
|
||||||
bpm_detect->priv->detect =
|
bpm_detect->priv->detect =
|
||||||
new soundtouch::BPMDetect (filter->format.channels,
|
new soundtouch::BPMDetect (GST_AUDIO_INFO_CHANNELS (&filter->info),
|
||||||
filter->format.rate);
|
GST_AUDIO_INFO_RATE (&filter->info));
|
||||||
#else
|
#else
|
||||||
bpm_detect->priv->detect =
|
bpm_detect->priv->detect =
|
||||||
new BPMDetect (filter->format.channels, filter->format.rate);
|
new BPMDetect (GST_AUDIO_INFO_CHANNELS (&filter->info),
|
||||||
|
GST_AUDIO_INFO_RATE (&filter->info));
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
nsamples = GST_BUFFER_SIZE (in) / (4 * filter->format.channels);
|
gst_buffer_map (in, &info, GST_MAP_READ);
|
||||||
|
|
||||||
|
nsamples = info.size / (4 * GST_AUDIO_INFO_CHANNELS (&filter->info));
|
||||||
|
|
||||||
/* For stereo BPMDetect->inputSamples() does downmixing into the input
|
/* For stereo BPMDetect->inputSamples() does downmixing into the input
|
||||||
* data but our buffer data shouldn't be modified.
|
* data but our buffer data shouldn't be modified.
|
||||||
*/
|
*/
|
||||||
if (filter->format.channels == 1) {
|
if (GST_AUDIO_INFO_CHANNELS (&filter->info) == 1) {
|
||||||
gfloat *inbuf = (gfloat *) GST_BUFFER_DATA (in);
|
gfloat *inbuf = (gfloat *) info.data;
|
||||||
|
|
||||||
while (nsamples > 0) {
|
while (nsamples > 0) {
|
||||||
bpm_detect->priv->detect->inputSamples (inbuf, MIN (nsamples, 2048));
|
bpm_detect->priv->detect->inputSamples (inbuf, MIN (nsamples, 2048));
|
||||||
|
@ -227,7 +225,7 @@ gst_bpm_detect_transform_ip (GstBaseTransform * trans, GstBuffer * in)
|
||||||
} else {
|
} else {
|
||||||
gfloat *inbuf, *intmp, data[2 * 2048];
|
gfloat *inbuf, *intmp, data[2 * 2048];
|
||||||
|
|
||||||
inbuf = (gfloat *) GST_BUFFER_DATA (in);
|
inbuf = (gfloat *) info.data;
|
||||||
intmp = data;
|
intmp = data;
|
||||||
|
|
||||||
while (nsamples > 0) {
|
while (nsamples > 0) {
|
||||||
|
@ -237,14 +235,15 @@ gst_bpm_detect_transform_ip (GstBaseTransform * trans, GstBuffer * in)
|
||||||
inbuf += 2048 * 2;
|
inbuf += 2048 * 2;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
gst_buffer_unmap (in, &info);
|
||||||
|
|
||||||
bpm = bpm_detect->priv->detect->getBpm ();
|
bpm = bpm_detect->priv->detect->getBpm ();
|
||||||
if (bpm >= 1.0 && fabs (bpm_detect->bpm - bpm) >= 1.0) {
|
if (bpm >= 1.0 && fabs (bpm_detect->bpm - bpm) >= 1.0) {
|
||||||
GstTagList *tags = gst_tag_list_new ();
|
GstTagList *tags = gst_tag_list_new_empty ();
|
||||||
|
|
||||||
gst_tag_list_add (tags, GST_TAG_MERGE_REPLACE_ALL, GST_TAG_BEATS_PER_MINUTE,
|
gst_tag_list_add (tags, GST_TAG_MERGE_REPLACE_ALL, GST_TAG_BEATS_PER_MINUTE,
|
||||||
bpm, (void *) NULL);
|
bpm, (void *) NULL);
|
||||||
gst_element_found_tags (GST_ELEMENT (bpm_detect), tags);
|
gst_pad_push_event (trans->srcpad, gst_event_new_tag ("bpmdetect", tags));
|
||||||
|
|
||||||
GST_INFO_OBJECT (bpm_detect, "Detected BPM: %lf\n", bpm);
|
GST_INFO_OBJECT (bpm_detect, "Detected BPM: %lf\n", bpm);
|
||||||
bpm_detect->bpm = bpm;
|
bpm_detect->bpm = bpm;
|
||||||
|
|
|
@ -35,7 +35,8 @@
|
||||||
#include <soundtouch/SoundTouch.h>
|
#include <soundtouch/SoundTouch.h>
|
||||||
|
|
||||||
#include <gst/gst.h>
|
#include <gst/gst.h>
|
||||||
#include <gst/controller/gstcontroller.h>
|
#include <gst/audio/audio.h>
|
||||||
|
|
||||||
#include "gstpitch.hh"
|
#include "gstpitch.hh"
|
||||||
#include <math.h>
|
#include <math.h>
|
||||||
|
|
||||||
|
@ -62,25 +63,22 @@ enum
|
||||||
};
|
};
|
||||||
|
|
||||||
#define SUPPORTED_CAPS \
|
#define SUPPORTED_CAPS \
|
||||||
GST_STATIC_CAPS( \
|
"audio/x-raw, " \
|
||||||
"audio/x-raw-float, " \
|
"format = (string) " GST_AUDIO_NE (F32) ", " \
|
||||||
"rate = (int) [ 8000, MAX ], " \
|
"rate = (int) [ 8000, MAX ], " \
|
||||||
"channels = (int) [ 1, 2 ], " \
|
"channels = (int) [ 1, 2 ]"
|
||||||
"endianness = (int) BYTE_ORDER, " \
|
|
||||||
"width = (int) 32" \
|
|
||||||
)
|
|
||||||
|
|
||||||
static GstStaticPadTemplate gst_pitch_sink_template =
|
static GstStaticPadTemplate gst_pitch_sink_template =
|
||||||
GST_STATIC_PAD_TEMPLATE ("sink",
|
GST_STATIC_PAD_TEMPLATE ("sink",
|
||||||
GST_PAD_SINK,
|
GST_PAD_SINK,
|
||||||
GST_PAD_ALWAYS,
|
GST_PAD_ALWAYS,
|
||||||
SUPPORTED_CAPS);
|
GST_STATIC_CAPS (SUPPORTED_CAPS));
|
||||||
|
|
||||||
static GstStaticPadTemplate gst_pitch_src_template =
|
static GstStaticPadTemplate gst_pitch_src_template =
|
||||||
GST_STATIC_PAD_TEMPLATE ("src",
|
GST_STATIC_PAD_TEMPLATE ("src",
|
||||||
GST_PAD_SRC,
|
GST_PAD_SRC,
|
||||||
GST_PAD_ALWAYS,
|
GST_PAD_ALWAYS,
|
||||||
SUPPORTED_CAPS);
|
GST_STATIC_CAPS (SUPPORTED_CAPS));
|
||||||
|
|
||||||
static void gst_pitch_dispose (GObject * object);
|
static void gst_pitch_dispose (GObject * object);
|
||||||
static void gst_pitch_set_property (GObject * object,
|
static void gst_pitch_set_property (GObject * object,
|
||||||
|
@ -89,32 +87,17 @@ static void gst_pitch_get_property (GObject * object,
|
||||||
guint prop_id, GValue * value, GParamSpec * pspec);
|
guint prop_id, GValue * value, GParamSpec * pspec);
|
||||||
|
|
||||||
|
|
||||||
static gboolean gst_pitch_sink_setcaps (GstPad * pad, GstCaps * caps);
|
static gboolean gst_pitch_setcaps (GstPitch * pitch, GstCaps * caps);
|
||||||
static GstFlowReturn gst_pitch_chain (GstPad * pad, GstBuffer * buffer);
|
static GstFlowReturn gst_pitch_chain (GstPad * pad, GstObject * parent, GstBuffer * buffer);
|
||||||
static GstStateChangeReturn gst_pitch_change_state (GstElement * element,
|
static GstStateChangeReturn gst_pitch_change_state (GstElement * element,
|
||||||
GstStateChange transition);
|
GstStateChange transition);
|
||||||
static gboolean gst_pitch_sink_event (GstPad * pad, GstEvent * event);
|
static gboolean gst_pitch_sink_event (GstPad * pad, GstObject * parent, GstEvent * event);
|
||||||
static gboolean gst_pitch_src_event (GstPad * pad, GstEvent * event);
|
static gboolean gst_pitch_src_event (GstPad * pad, GstObject * parent, GstEvent * event);
|
||||||
|
|
||||||
static gboolean gst_pitch_src_query (GstPad * pad, GstQuery * query);
|
static gboolean gst_pitch_src_query (GstPad * pad, GstObject * parent, GstQuery * query);
|
||||||
static const GstQueryType *gst_pitch_get_query_types (GstPad * pad);
|
|
||||||
|
|
||||||
GST_BOILERPLATE (GstPitch, gst_pitch, GstElement, GST_TYPE_ELEMENT);
|
#define gst_pitch_parent_class parent_class
|
||||||
|
G_DEFINE_TYPE (GstPitch, gst_pitch, GST_TYPE_ELEMENT);
|
||||||
static void
|
|
||||||
gst_pitch_base_init (gpointer g_class)
|
|
||||||
{
|
|
||||||
GstElementClass *gstelement_class = GST_ELEMENT_CLASS (g_class);
|
|
||||||
|
|
||||||
gst_element_class_add_pad_template (gstelement_class,
|
|
||||||
gst_static_pad_template_get (&gst_pitch_src_template));
|
|
||||||
gst_element_class_add_pad_template (gstelement_class,
|
|
||||||
gst_static_pad_template_get (&gst_pitch_sink_template));
|
|
||||||
|
|
||||||
gst_element_class_set_details_simple (gstelement_class, "Pitch controller",
|
|
||||||
"Filter/Converter/Audio", "Control the pitch of an audio stream",
|
|
||||||
"Wouter Paesen <wouter@blue-gate.be>");
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
gst_pitch_class_init (GstPitchClass * klass)
|
gst_pitch_class_init (GstPitchClass * klass)
|
||||||
|
@ -128,10 +111,11 @@ gst_pitch_class_init (GstPitchClass * klass)
|
||||||
GST_DEBUG_CATEGORY_INIT (pitch_debug, "pitch", 0,
|
GST_DEBUG_CATEGORY_INIT (pitch_debug, "pitch", 0,
|
||||||
"audio pitch control element");
|
"audio pitch control element");
|
||||||
|
|
||||||
|
g_type_class_add_private (gobject_class, sizeof (GstPitchPrivate));
|
||||||
|
|
||||||
gobject_class->set_property = gst_pitch_set_property;
|
gobject_class->set_property = gst_pitch_set_property;
|
||||||
gobject_class->get_property = gst_pitch_get_property;
|
gobject_class->get_property = gst_pitch_get_property;
|
||||||
gobject_class->dispose = GST_DEBUG_FUNCPTR (gst_pitch_dispose);
|
gobject_class->dispose = GST_DEBUG_FUNCPTR (gst_pitch_dispose);
|
||||||
element_class->change_state = GST_DEBUG_FUNCPTR (gst_pitch_change_state);
|
|
||||||
|
|
||||||
g_object_class_install_property (gobject_class, ARG_PITCH,
|
g_object_class_install_property (gobject_class, ARG_PITCH,
|
||||||
g_param_spec_float ("pitch", "Pitch",
|
g_param_spec_float ("pitch", "Pitch",
|
||||||
|
@ -153,11 +137,20 @@ gst_pitch_class_init (GstPitchClass * klass)
|
||||||
"Output rate on downstream segment events", 0.1, 10.0, 1.0,
|
"Output rate on downstream segment events", 0.1, 10.0, 1.0,
|
||||||
(GParamFlags) (G_PARAM_READWRITE | GST_PARAM_CONTROLLABLE | G_PARAM_STATIC_STRINGS)));
|
(GParamFlags) (G_PARAM_READWRITE | GST_PARAM_CONTROLLABLE | G_PARAM_STATIC_STRINGS)));
|
||||||
|
|
||||||
g_type_class_add_private (gobject_class, sizeof (GstPitchPrivate));
|
element_class->change_state = GST_DEBUG_FUNCPTR (gst_pitch_change_state);
|
||||||
|
|
||||||
|
gst_element_class_add_pad_template (element_class,
|
||||||
|
gst_static_pad_template_get (&gst_pitch_src_template));
|
||||||
|
gst_element_class_add_pad_template (element_class,
|
||||||
|
gst_static_pad_template_get (&gst_pitch_sink_template));
|
||||||
|
|
||||||
|
gst_element_class_set_details_simple (element_class, "Pitch controller",
|
||||||
|
"Filter/Converter/Audio", "Control the pitch of an audio stream",
|
||||||
|
"Wouter Paesen <wouter@blue-gate.be>");
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
gst_pitch_init (GstPitch * pitch, GstPitchClass * pitch_class)
|
gst_pitch_init (GstPitch * pitch)
|
||||||
{
|
{
|
||||||
pitch->priv =
|
pitch->priv =
|
||||||
G_TYPE_INSTANCE_GET_PRIVATE ((pitch), GST_TYPE_PITCH, GstPitchPrivate);
|
G_TYPE_INSTANCE_GET_PRIVATE ((pitch), GST_TYPE_PITCH, GstPitchPrivate);
|
||||||
|
@ -168,24 +161,16 @@ gst_pitch_init (GstPitch * pitch, GstPitchClass * pitch_class)
|
||||||
GST_DEBUG_FUNCPTR (gst_pitch_chain));
|
GST_DEBUG_FUNCPTR (gst_pitch_chain));
|
||||||
gst_pad_set_event_function (pitch->sinkpad,
|
gst_pad_set_event_function (pitch->sinkpad,
|
||||||
GST_DEBUG_FUNCPTR (gst_pitch_sink_event));
|
GST_DEBUG_FUNCPTR (gst_pitch_sink_event));
|
||||||
gst_pad_set_setcaps_function (pitch->sinkpad,
|
GST_PAD_SET_PROXY_CAPS (pitch->sinkpad);
|
||||||
GST_DEBUG_FUNCPTR (gst_pitch_sink_setcaps));
|
|
||||||
gst_pad_set_getcaps_function (pitch->sinkpad,
|
|
||||||
GST_DEBUG_FUNCPTR (gst_pad_proxy_getcaps));
|
|
||||||
gst_element_add_pad (GST_ELEMENT (pitch), pitch->sinkpad);
|
gst_element_add_pad (GST_ELEMENT (pitch), pitch->sinkpad);
|
||||||
|
|
||||||
pitch->srcpad =
|
pitch->srcpad =
|
||||||
gst_pad_new_from_static_template (&gst_pitch_src_template, "src");
|
gst_pad_new_from_static_template (&gst_pitch_src_template, "src");
|
||||||
gst_pad_set_event_function (pitch->srcpad,
|
gst_pad_set_event_function (pitch->srcpad,
|
||||||
GST_DEBUG_FUNCPTR (gst_pitch_src_event));
|
GST_DEBUG_FUNCPTR (gst_pitch_src_event));
|
||||||
gst_pad_set_query_type_function (pitch->srcpad,
|
|
||||||
GST_DEBUG_FUNCPTR (gst_pitch_get_query_types));
|
|
||||||
gst_pad_set_query_function (pitch->srcpad,
|
gst_pad_set_query_function (pitch->srcpad,
|
||||||
GST_DEBUG_FUNCPTR (gst_pitch_src_query));
|
GST_DEBUG_FUNCPTR (gst_pitch_src_query));
|
||||||
gst_pad_set_setcaps_function (pitch->srcpad,
|
GST_PAD_SET_PROXY_CAPS (pitch->sinkpad);
|
||||||
GST_DEBUG_FUNCPTR (gst_pitch_sink_setcaps));
|
|
||||||
gst_pad_set_getcaps_function (pitch->srcpad,
|
|
||||||
GST_DEBUG_FUNCPTR (gst_pad_proxy_getcaps));
|
|
||||||
gst_element_add_pad (GST_ELEMENT (pitch), pitch->srcpad);
|
gst_element_add_pad (GST_ELEMENT (pitch), pitch->srcpad);
|
||||||
|
|
||||||
pitch->priv->st = new soundtouch::SoundTouch ();
|
pitch->priv->st = new soundtouch::SoundTouch ();
|
||||||
|
@ -296,22 +281,14 @@ gst_pitch_get_property (GObject * object, guint prop_id,
|
||||||
}
|
}
|
||||||
|
|
||||||
static gboolean
|
static gboolean
|
||||||
gst_pitch_sink_setcaps (GstPad * pad, GstCaps * caps)
|
gst_pitch_setcaps (GstPitch * pitch, GstCaps * caps)
|
||||||
{
|
{
|
||||||
GstPitch *pitch;
|
|
||||||
GstPitchPrivate *priv;
|
GstPitchPrivate *priv;
|
||||||
GstStructure *structure;
|
GstStructure *structure;
|
||||||
GstPad *otherpad;
|
|
||||||
gint rate, channels;
|
gint rate, channels;
|
||||||
|
|
||||||
pitch = GST_PITCH (GST_PAD_PARENT (pad));
|
|
||||||
priv = GST_PITCH_GET_PRIVATE (pitch);
|
priv = GST_PITCH_GET_PRIVATE (pitch);
|
||||||
|
|
||||||
otherpad = (pad == pitch->srcpad) ? pitch->sinkpad : pitch->srcpad;
|
|
||||||
|
|
||||||
if (!gst_pad_set_caps (otherpad, caps))
|
|
||||||
return FALSE;
|
|
||||||
|
|
||||||
structure = gst_caps_get_structure (caps, 0);
|
structure = gst_caps_get_structure (caps, 0);
|
||||||
|
|
||||||
if (!gst_structure_get_int (structure, "rate", &rate) ||
|
if (!gst_structure_get_int (structure, "rate", &rate) ||
|
||||||
|
@ -364,6 +341,7 @@ gst_pitch_prepare_buffer (GstPitch * pitch)
|
||||||
GstPitchPrivate *priv;
|
GstPitchPrivate *priv;
|
||||||
guint samples;
|
guint samples;
|
||||||
GstBuffer *buffer;
|
GstBuffer *buffer;
|
||||||
|
GstMapInfo info;
|
||||||
|
|
||||||
priv = GST_PITCH_GET_PRIVATE (pitch);
|
priv = GST_PITCH_GET_PRIVATE (pitch);
|
||||||
|
|
||||||
|
@ -373,15 +351,12 @@ gst_pitch_prepare_buffer (GstPitch * pitch)
|
||||||
if (samples == 0)
|
if (samples == 0)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
if (gst_pad_alloc_buffer_and_set_caps (pitch->srcpad, GST_BUFFER_OFFSET_NONE,
|
|
||||||
samples * pitch->sample_size, GST_PAD_CAPS (pitch->srcpad), &buffer)
|
|
||||||
!= GST_FLOW_OK) {
|
|
||||||
buffer = gst_buffer_new_and_alloc (samples * pitch->sample_size);
|
buffer = gst_buffer_new_and_alloc (samples * pitch->sample_size);
|
||||||
gst_buffer_set_caps (buffer, GST_PAD_CAPS (pitch->srcpad));
|
|
||||||
}
|
|
||||||
|
|
||||||
|
gst_buffer_map (buffer, &info, (GstMapFlags) GST_MAP_READWRITE);
|
||||||
samples =
|
samples =
|
||||||
priv->st->receiveSamples ((gfloat *) GST_BUFFER_DATA (buffer), samples);
|
priv->st->receiveSamples ((gfloat *) info.data, samples);
|
||||||
|
gst_buffer_unmap (buffer, &info);
|
||||||
|
|
||||||
if (samples <= 0) {
|
if (samples <= 0) {
|
||||||
gst_buffer_unref (buffer);
|
gst_buffer_unref (buffer);
|
||||||
|
@ -422,12 +397,12 @@ gst_pitch_flush_buffer (GstPitch * pitch, gboolean send)
|
||||||
}
|
}
|
||||||
|
|
||||||
static gboolean
|
static gboolean
|
||||||
gst_pitch_src_event (GstPad * pad, GstEvent * event)
|
gst_pitch_src_event (GstPad * pad, GstObject * parent, GstEvent * event)
|
||||||
{
|
{
|
||||||
GstPitch *pitch;
|
GstPitch *pitch;
|
||||||
gboolean res;
|
gboolean res;
|
||||||
|
|
||||||
pitch = GST_PITCH (gst_pad_get_parent (pad));
|
pitch = GST_PITCH (parent);
|
||||||
|
|
||||||
GST_DEBUG_OBJECT (pad, "received %s event", GST_EVENT_TYPE_NAME (event));
|
GST_DEBUG_OBJECT (pad, "received %s event", GST_EVENT_TYPE_NAME (event));
|
||||||
|
|
||||||
|
@ -457,21 +432,18 @@ gst_pitch_src_event (GstPad * pad, GstEvent * event)
|
||||||
|
|
||||||
event = gst_event_new_seek (rate, format, flags,
|
event = gst_event_new_seek (rate, format, flags,
|
||||||
cur_type, cur, stop_type, stop);
|
cur_type, cur, stop_type, stop);
|
||||||
res = gst_pad_event_default (pad, event);
|
res = gst_pad_event_default (pad, parent, event);
|
||||||
} else {
|
} else {
|
||||||
GST_WARNING_OBJECT (pitch,
|
GST_WARNING_OBJECT (pitch,
|
||||||
"Seeking only supported in TIME or DEFAULT format");
|
"Seeking only supported in TIME or DEFAULT format");
|
||||||
res = FALSE;
|
res = FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
default:
|
default:
|
||||||
res = gst_pad_event_default (pad, event);
|
res = gst_pad_event_default (pad, parent, event);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
gst_object_unref (pitch);
|
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -557,22 +529,8 @@ gst_pitch_convert (GstPitch * pitch,
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
static const GstQueryType *
|
|
||||||
gst_pitch_get_query_types (GstPad * pad)
|
|
||||||
{
|
|
||||||
static const GstQueryType types[] = {
|
|
||||||
GST_QUERY_POSITION,
|
|
||||||
GST_QUERY_DURATION,
|
|
||||||
GST_QUERY_CONVERT,
|
|
||||||
GST_QUERY_LATENCY,
|
|
||||||
GST_QUERY_NONE
|
|
||||||
};
|
|
||||||
|
|
||||||
return types;
|
|
||||||
}
|
|
||||||
|
|
||||||
static gboolean
|
static gboolean
|
||||||
gst_pitch_src_query (GstPad * pad, GstQuery * query)
|
gst_pitch_src_query (GstPad * pad, GstObject * parent, GstQuery * query)
|
||||||
{
|
{
|
||||||
GstPitch *pitch;
|
GstPitch *pitch;
|
||||||
gboolean res = FALSE;
|
gboolean res = FALSE;
|
||||||
|
@ -580,8 +538,10 @@ gst_pitch_src_query (GstPad * pad, GstQuery * query)
|
||||||
gint64 next_buffer_offset;
|
gint64 next_buffer_offset;
|
||||||
GstClockTime next_buffer_time;
|
GstClockTime next_buffer_time;
|
||||||
|
|
||||||
pitch = GST_PITCH (gst_pad_get_parent (pad));
|
pitch = GST_PITCH (parent);
|
||||||
|
|
||||||
GST_LOG ("%s query", GST_QUERY_TYPE_NAME (query));
|
GST_LOG ("%s query", GST_QUERY_TYPE_NAME (query));
|
||||||
|
|
||||||
GST_OBJECT_LOCK (pitch);
|
GST_OBJECT_LOCK (pitch);
|
||||||
stream_time_ratio = pitch->priv->stream_time_ratio;
|
stream_time_ratio = pitch->priv->stream_time_ratio;
|
||||||
next_buffer_time = pitch->next_buffer_time;
|
next_buffer_time = pitch->next_buffer_time;
|
||||||
|
@ -593,7 +553,7 @@ gst_pitch_src_query (GstPad * pad, GstQuery * query)
|
||||||
GstFormat format;
|
GstFormat format;
|
||||||
gint64 duration;
|
gint64 duration;
|
||||||
|
|
||||||
if (!gst_pad_query_default (pad, query)) {
|
if (!gst_pad_query_default (pad, parent, query)) {
|
||||||
GST_DEBUG_OBJECT (pitch, "upstream provided no duration");
|
GST_DEBUG_OBJECT (pitch, "upstream provided no duration");
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -689,11 +649,10 @@ gst_pitch_src_query (GstPad * pad, GstQuery * query)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
default:
|
default:
|
||||||
res = gst_pad_query_default (pad, query);
|
res = gst_pad_query_default (pad, parent, query);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
gst_object_unref (pitch);
|
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -706,12 +665,11 @@ gst_pitch_src_query (GstPad * pad, GstQuery * query)
|
||||||
static gboolean
|
static gboolean
|
||||||
gst_pitch_process_segment (GstPitch * pitch, GstEvent ** event)
|
gst_pitch_process_segment (GstPitch * pitch, GstEvent ** event)
|
||||||
{
|
{
|
||||||
GstFormat format, conv_format;
|
GstFormat conv_format;
|
||||||
gint64 start_value, stop_value, base;
|
|
||||||
gint64 next_offset = 0, next_time = 0;
|
gint64 next_offset = 0, next_time = 0;
|
||||||
gboolean update = FALSE;
|
gdouble out_seg_rate, our_arate;
|
||||||
gdouble rate, out_seg_rate, arate, our_arate;
|
|
||||||
gfloat stream_time_ratio;
|
gfloat stream_time_ratio;
|
||||||
|
GstSegment seg;
|
||||||
|
|
||||||
g_return_val_if_fail (event, FALSE);
|
g_return_val_if_fail (event, FALSE);
|
||||||
|
|
||||||
|
@ -720,30 +678,27 @@ gst_pitch_process_segment (GstPitch * pitch, GstEvent ** event)
|
||||||
out_seg_rate = pitch->out_seg_rate;
|
out_seg_rate = pitch->out_seg_rate;
|
||||||
GST_OBJECT_UNLOCK (pitch);
|
GST_OBJECT_UNLOCK (pitch);
|
||||||
|
|
||||||
gst_event_parse_new_segment_full (*event, &update, &rate, &arate, &format, &start_value,
|
gst_event_copy_segment (*event, &seg);
|
||||||
&stop_value, &base);
|
|
||||||
|
|
||||||
if (format != GST_FORMAT_TIME && format != GST_FORMAT_DEFAULT) {
|
if (seg.format != GST_FORMAT_TIME && seg.format != GST_FORMAT_DEFAULT) {
|
||||||
GST_WARNING_OBJECT (pitch,
|
GST_WARNING_OBJECT (pitch,
|
||||||
"Only NEWSEGMENT in TIME or DEFAULT format supported, sending"
|
"Only NEWSEGMENT in TIME or DEFAULT format supported, sending"
|
||||||
"open ended NEWSEGMENT in TIME format.");
|
"open ended NEWSEGMENT in TIME format.");
|
||||||
gst_event_unref (*event);
|
seg.format = GST_FORMAT_TIME;
|
||||||
*event =
|
seg.start = 0;
|
||||||
gst_event_new_new_segment_full (update, rate, arate, GST_FORMAT_TIME, 0, -1, 0);
|
seg.stop = -1;
|
||||||
start_value = 0;
|
seg.time = 0;
|
||||||
stop_value = -1;
|
|
||||||
base = 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Figure out how much of the incoming 'rate' we'll apply ourselves */
|
/* Figure out how much of the incoming 'rate' we'll apply ourselves */
|
||||||
our_arate = rate / out_seg_rate;
|
our_arate = seg.rate / out_seg_rate;
|
||||||
/* update the output rate variables */
|
/* update the output rate variables */
|
||||||
rate = out_seg_rate;
|
seg.rate = out_seg_rate;
|
||||||
arate *= our_arate;
|
seg.applied_rate *= our_arate;
|
||||||
|
|
||||||
GST_LOG_OBJECT (pitch->sinkpad,
|
GST_LOG_OBJECT (pitch->sinkpad,
|
||||||
"segment %" G_GINT64_FORMAT " - %" G_GINT64_FORMAT " (%d)", start_value,
|
"segment %" G_GINT64_FORMAT " - %" G_GINT64_FORMAT " (%d)", seg.start,
|
||||||
stop_value, format);
|
seg.stop, seg.format);
|
||||||
|
|
||||||
stream_time_ratio = pitch->tempo * pitch->rate * pitch->seg_arate;
|
stream_time_ratio = pitch->tempo * pitch->rate * pitch->seg_arate;
|
||||||
|
|
||||||
|
@ -759,20 +714,20 @@ gst_pitch_process_segment (GstPitch * pitch, GstEvent ** event)
|
||||||
pitch->priv->st->setTempo (pitch->tempo * pitch->seg_arate);
|
pitch->priv->st->setTempo (pitch->tempo * pitch->seg_arate);
|
||||||
GST_OBJECT_UNLOCK (pitch);
|
GST_OBJECT_UNLOCK (pitch);
|
||||||
|
|
||||||
start_value = (gint64) (start_value / stream_time_ratio);
|
seg.start = (gint64) (seg.start / stream_time_ratio);
|
||||||
if (stop_value != -1)
|
if (seg.stop != (guint64) -1)
|
||||||
stop_value = (gint64) (stop_value / stream_time_ratio);
|
seg.stop = (gint64) (seg.stop / stream_time_ratio);
|
||||||
base = (gint64) (base / stream_time_ratio);
|
seg.time = (gint64) (seg.time / stream_time_ratio);
|
||||||
|
|
||||||
conv_format = GST_FORMAT_TIME;
|
conv_format = GST_FORMAT_TIME;
|
||||||
if (!gst_pitch_convert (pitch, format, start_value, &conv_format, &next_time)) {
|
if (!gst_pitch_convert (pitch, seg.format, seg.start, &conv_format, &next_time)) {
|
||||||
GST_LOG_OBJECT (pitch->sinkpad,
|
GST_LOG_OBJECT (pitch->sinkpad,
|
||||||
"could not convert segment start value to time");
|
"could not convert segment start value to time");
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
conv_format = GST_FORMAT_DEFAULT;
|
conv_format = GST_FORMAT_DEFAULT;
|
||||||
if (!gst_pitch_convert (pitch, format, start_value, &conv_format,
|
if (!gst_pitch_convert (pitch, seg.format, seg.start, &conv_format,
|
||||||
&next_offset)) {
|
&next_offset)) {
|
||||||
GST_LOG_OBJECT (pitch->sinkpad,
|
GST_LOG_OBJECT (pitch->sinkpad,
|
||||||
"could not convert segment start value to offset");
|
"could not convert segment start value to offset");
|
||||||
|
@ -783,19 +738,18 @@ gst_pitch_process_segment (GstPitch * pitch, GstEvent ** event)
|
||||||
pitch->next_buffer_offset = next_offset;
|
pitch->next_buffer_offset = next_offset;
|
||||||
|
|
||||||
gst_event_unref (*event);
|
gst_event_unref (*event);
|
||||||
*event = gst_event_new_new_segment_full (update, rate, arate, format,
|
*event = gst_event_new_segment (&seg);
|
||||||
start_value, stop_value, base);
|
|
||||||
|
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
static gboolean
|
static gboolean
|
||||||
gst_pitch_sink_event (GstPad * pad, GstEvent * event)
|
gst_pitch_sink_event (GstPad * pad, GstObject * parent, GstEvent * event)
|
||||||
{
|
{
|
||||||
gboolean res = TRUE;
|
gboolean res = TRUE;
|
||||||
GstPitch *pitch;
|
GstPitch *pitch;
|
||||||
|
|
||||||
pitch = GST_PITCH (gst_pad_get_parent (pad));
|
pitch = GST_PITCH (parent);
|
||||||
|
|
||||||
GST_LOG_OBJECT (pad, "received %s event", GST_EVENT_TYPE_NAME (event));
|
GST_LOG_OBJECT (pad, "received %s event", GST_EVENT_TYPE_NAME (event));
|
||||||
|
|
||||||
|
@ -812,7 +766,7 @@ gst_pitch_sink_event (GstPad * pad, GstEvent * event)
|
||||||
pitch->priv->st->clear ();
|
pitch->priv->st->clear ();
|
||||||
pitch->min_latency = pitch->max_latency = 0;
|
pitch->min_latency = pitch->max_latency = 0;
|
||||||
break;
|
break;
|
||||||
case GST_EVENT_NEWSEGMENT:
|
case GST_EVENT_SEGMENT:
|
||||||
if (!gst_pitch_process_segment (pitch, &event)) {
|
if (!gst_pitch_process_segment (pitch, &event)) {
|
||||||
GST_LOG_OBJECT (pad, "not enough data known, stalling segment");
|
GST_LOG_OBJECT (pad, "not enough data known, stalling segment");
|
||||||
if (GST_PITCH_GET_PRIVATE (pitch)->pending_segment)
|
if (GST_PITCH_GET_PRIVATE (pitch)->pending_segment)
|
||||||
|
@ -823,15 +777,26 @@ gst_pitch_sink_event (GstPad * pad, GstEvent * event)
|
||||||
pitch->priv->st->clear ();
|
pitch->priv->st->clear ();
|
||||||
pitch->min_latency = pitch->max_latency = 0;
|
pitch->min_latency = pitch->max_latency = 0;
|
||||||
break;
|
break;
|
||||||
|
case GST_EVENT_CAPS:
|
||||||
|
{
|
||||||
|
GstCaps * caps;
|
||||||
|
|
||||||
|
gst_event_parse_caps (event, &caps);
|
||||||
|
res = gst_pitch_setcaps (pitch, caps);
|
||||||
|
if (!res) {
|
||||||
|
gst_event_unref (event);
|
||||||
|
goto done;
|
||||||
|
}
|
||||||
|
}
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* and forward it */
|
/* and forward it */
|
||||||
if (event)
|
if (event)
|
||||||
res = gst_pad_event_default (pad, event);
|
res = gst_pad_event_default (pad, parent, event);
|
||||||
|
|
||||||
gst_object_unref (pitch);
|
done:
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -862,22 +827,23 @@ gst_pitch_update_latency (GstPitch * pitch, GstClockTime timestamp)
|
||||||
}
|
}
|
||||||
|
|
||||||
static GstFlowReturn
|
static GstFlowReturn
|
||||||
gst_pitch_chain (GstPad * pad, GstBuffer * buffer)
|
gst_pitch_chain (GstPad * pad, GstObject * parent, GstBuffer * buffer)
|
||||||
{
|
{
|
||||||
GstPitch *pitch;
|
GstPitch *pitch;
|
||||||
GstPitchPrivate *priv;
|
GstPitchPrivate *priv;
|
||||||
GstClockTime timestamp;
|
GstClockTime timestamp;
|
||||||
|
GstMapInfo info;
|
||||||
|
|
||||||
pitch = GST_PITCH (GST_PAD_PARENT (pad));
|
pitch = GST_PITCH (parent);
|
||||||
priv = GST_PITCH_GET_PRIVATE (pitch);
|
priv = GST_PITCH_GET_PRIVATE (pitch);
|
||||||
|
|
||||||
gst_object_sync_values (G_OBJECT (pitch), pitch->next_buffer_time);
|
gst_object_sync_values (GST_OBJECT (pitch), pitch->next_buffer_time);
|
||||||
|
|
||||||
timestamp = GST_BUFFER_TIMESTAMP (buffer);
|
timestamp = GST_BUFFER_TIMESTAMP (buffer);
|
||||||
|
|
||||||
/* push the received samples on the soundtouch buffer */
|
/* push the received samples on the soundtouch buffer */
|
||||||
GST_LOG_OBJECT (pitch, "incoming buffer (%d samples)",
|
GST_LOG_OBJECT (pitch, "incoming buffer (%d samples)",
|
||||||
(gint) (GST_BUFFER_SIZE (buffer) / pitch->sample_size));
|
(gint) (gst_buffer_get_size (buffer) / pitch->sample_size));
|
||||||
|
|
||||||
if (GST_PITCH_GET_PRIVATE (pitch)->pending_segment) {
|
if (GST_PITCH_GET_PRIVATE (pitch)->pending_segment) {
|
||||||
GstEvent *event =
|
GstEvent *event =
|
||||||
|
@ -885,11 +851,13 @@ gst_pitch_chain (GstPad * pad, GstBuffer * buffer)
|
||||||
|
|
||||||
GST_LOG_OBJECT (pitch, "processing stalled segment");
|
GST_LOG_OBJECT (pitch, "processing stalled segment");
|
||||||
if (!gst_pitch_process_segment (pitch, &event)) {
|
if (!gst_pitch_process_segment (pitch, &event)) {
|
||||||
|
gst_buffer_unref (buffer);
|
||||||
gst_event_unref (event);
|
gst_event_unref (event);
|
||||||
return GST_FLOW_ERROR;
|
return GST_FLOW_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!gst_pad_event_default (pitch->sinkpad, event)) {
|
if (!gst_pad_event_default (pitch->sinkpad, parent, event)) {
|
||||||
|
gst_buffer_unref (buffer);
|
||||||
gst_event_unref (event);
|
gst_event_unref (event);
|
||||||
return GST_FLOW_ERROR;
|
return GST_FLOW_ERROR;
|
||||||
}
|
}
|
||||||
|
@ -898,14 +866,14 @@ gst_pitch_chain (GstPad * pad, GstBuffer * buffer)
|
||||||
GST_PITCH_GET_PRIVATE (pitch)->pending_segment = NULL;
|
GST_PITCH_GET_PRIVATE (pitch)->pending_segment = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
priv->st->putSamples ((gfloat *) GST_BUFFER_DATA (buffer),
|
gst_buffer_map (buffer, &info, GST_MAP_READ);
|
||||||
GST_BUFFER_SIZE (buffer) / pitch->sample_size);
|
priv->st->putSamples ((gfloat *) info.data, info.size / pitch->sample_size);
|
||||||
|
gst_buffer_unmap (buffer, &info);
|
||||||
gst_buffer_unref (buffer);
|
gst_buffer_unref (buffer);
|
||||||
|
|
||||||
/* Calculate latency */
|
/* Calculate latency */
|
||||||
|
|
||||||
gst_pitch_update_latency (pitch, timestamp);
|
gst_pitch_update_latency (pitch, timestamp);
|
||||||
|
|
||||||
/* and try to extract some samples from the soundtouch buffer */
|
/* and try to extract some samples from the soundtouch buffer */
|
||||||
if (!priv->st->isEmpty ()) {
|
if (!priv->st->isEmpty ()) {
|
||||||
GstBuffer *out_buffer;
|
GstBuffer *out_buffer;
|
||||||
|
@ -939,7 +907,7 @@ gst_pitch_change_state (GstElement * element, GstStateChange transition)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
ret = parent_class->change_state (element, transition);
|
ret = GST_ELEMENT_CLASS (parent_class)->change_state (element, transition);
|
||||||
if (ret != GST_STATE_CHANGE_SUCCESS)
|
if (ret != GST_STATE_CHANGE_SUCCESS)
|
||||||
return ret;
|
return ret;
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue