gst/audiotestsrc/gstaudiotestsrc.*: Define the default property values in the usual place.

Original commit message from CVS:
* gst/audiotestsrc/gstaudiotestsrc.c:
(gst_audio_test_src_class_init), (gst_audio_test_src_init),
(gst_audio_test_src_src_fixate), (gst_audio_test_src_setcaps),
(gst_audio_test_src_start), (gst_audio_test_src_stop),
(gst_audio_test_src_do_seek), (gst_audio_test_src_check_get_range),
(gst_audio_test_src_create):
* gst/audiotestsrc/gstaudiotestsrc.h:
Define the default property values in the usual place.
Implement start/stop to reset values correctly.
Calculate the sample size only once when we negotiate.
Rename some values to make more sense.
Keep track of our byte range.
Add support for pull based scheduling. Disabled for now until we have
the whole stack working.
Set the BUFFER_OFFSET correctly.
This commit is contained in:
Wim Taymans 2008-10-10 15:45:15 +00:00
parent b735321f58
commit 81f5117fa9
3 changed files with 172 additions and 67 deletions

View file

@ -1,3 +1,21 @@
2008-10-10 Wim Taymans <wim.taymans@collabora.co.uk>
* gst/audiotestsrc/gstaudiotestsrc.c:
(gst_audio_test_src_class_init), (gst_audio_test_src_init),
(gst_audio_test_src_src_fixate), (gst_audio_test_src_setcaps),
(gst_audio_test_src_start), (gst_audio_test_src_stop),
(gst_audio_test_src_do_seek), (gst_audio_test_src_check_get_range),
(gst_audio_test_src_create):
* gst/audiotestsrc/gstaudiotestsrc.h:
Define the default property values in the usual place.
Implement start/stop to reset values correctly.
Calculate the sample size only once when we negotiate.
Rename some values to make more sense.
Keep track of our byte range.
Add support for pull based scheduling. Disabled for now until we have
the whole stack working.
Set the BUFFER_OFFSET correctly.
2008-10-10 Sebastian Dröge <sebastian.droege@collabora.co.uk> 2008-10-10 Sebastian Dröge <sebastian.droege@collabora.co.uk>
Based on a patch by: xavierb at gmail dot com Based on a patch by: xavierb at gmail dot com

View file

@ -67,6 +67,13 @@ GST_ELEMENT_DETAILS ("Audio test source",
"Creates audio test signals of given frequency and volume", "Creates audio test signals of given frequency and volume",
"Stefan Kost <ensonic@users.sf.net>"); "Stefan Kost <ensonic@users.sf.net>");
#define DEFAULT_SAMPLES_PER_BUFFER 1024
#define DEFAULT_WAVE GST_AUDIO_TEST_SRC_WAVE_SINE
#define DEFAULT_FREQ 440.0
#define DEFAULT_VOLUME 0.8
#define DEFAULT_IS_LIVE FALSE
#define DEFAULT_TIMESTAMP_OFFSET G_GINT64_CONSTANT (0)
#define DEFAULT_CAN_ACTIVATE_PULL FALSE
enum enum
{ {
@ -77,6 +84,7 @@ enum
PROP_VOLUME, PROP_VOLUME,
PROP_IS_LIVE, PROP_IS_LIVE,
PROP_TIMESTAMP_OFFSET, PROP_TIMESTAMP_OFFSET,
PROP_LAST
}; };
@ -143,6 +151,7 @@ static gboolean gst_audio_test_src_setcaps (GstBaseSrc * basesrc,
static void gst_audio_test_src_src_fixate (GstPad * pad, GstCaps * caps); static void gst_audio_test_src_src_fixate (GstPad * pad, GstCaps * caps);
static gboolean gst_audio_test_src_is_seekable (GstBaseSrc * basesrc); static gboolean gst_audio_test_src_is_seekable (GstBaseSrc * basesrc);
static gboolean gst_audio_test_src_check_get_range (GstBaseSrc * basesrc);
static gboolean gst_audio_test_src_do_seek (GstBaseSrc * basesrc, static gboolean gst_audio_test_src_do_seek (GstBaseSrc * basesrc,
GstSegment * segment); GstSegment * segment);
static gboolean gst_audio_test_src_query (GstBaseSrc * basesrc, static gboolean gst_audio_test_src_query (GstBaseSrc * basesrc,
@ -152,6 +161,8 @@ static void gst_audio_test_src_change_wave (GstAudioTestSrc * src);
static void gst_audio_test_src_get_times (GstBaseSrc * basesrc, static void gst_audio_test_src_get_times (GstBaseSrc * basesrc,
GstBuffer * buffer, GstClockTime * start, GstClockTime * end); GstBuffer * buffer, GstClockTime * start, GstClockTime * end);
static gboolean gst_audio_test_src_start (GstBaseSrc * basesrc);
static gboolean gst_audio_test_src_stop (GstBaseSrc * basesrc);
static GstFlowReturn gst_audio_test_src_create (GstBaseSrc * basesrc, static GstFlowReturn gst_audio_test_src_create (GstBaseSrc * basesrc,
guint64 offset, guint length, GstBuffer ** buffer); guint64 offset, guint length, GstBuffer ** buffer);
@ -181,35 +192,42 @@ gst_audio_test_src_class_init (GstAudioTestSrcClass * klass)
g_object_class_install_property (gobject_class, PROP_SAMPLES_PER_BUFFER, g_object_class_install_property (gobject_class, PROP_SAMPLES_PER_BUFFER,
g_param_spec_int ("samplesperbuffer", "Samples per buffer", g_param_spec_int ("samplesperbuffer", "Samples per buffer",
"Number of samples in each outgoing buffer", "Number of samples in each outgoing buffer",
1, G_MAXINT, 1024, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); 1, G_MAXINT, DEFAULT_SAMPLES_PER_BUFFER,
g_object_class_install_property (gobject_class, PROP_WAVE, g_param_spec_enum ("wave", "Waveform", "Oscillator waveform", GST_TYPE_AUDIO_TEST_SRC_WAVE, /* enum type */ G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
GST_AUDIO_TEST_SRC_WAVE_SINE, /* default value */ g_object_class_install_property (gobject_class, PROP_WAVE,
g_param_spec_enum ("wave", "Waveform", "Oscillator waveform",
GST_TYPE_AUDIO_TEST_SRC_WAVE, GST_AUDIO_TEST_SRC_WAVE_SINE,
G_PARAM_READWRITE | GST_PARAM_CONTROLLABLE | G_PARAM_STATIC_STRINGS)); G_PARAM_READWRITE | GST_PARAM_CONTROLLABLE | G_PARAM_STATIC_STRINGS));
g_object_class_install_property (gobject_class, PROP_FREQ, g_object_class_install_property (gobject_class, PROP_FREQ,
g_param_spec_double ("freq", "Frequency", "Frequency of test signal", g_param_spec_double ("freq", "Frequency", "Frequency of test signal",
0.0, 20000.0, 440.0, 0.0, 20000.0, DEFAULT_FREQ,
G_PARAM_READWRITE | GST_PARAM_CONTROLLABLE | G_PARAM_STATIC_STRINGS)); G_PARAM_READWRITE | GST_PARAM_CONTROLLABLE | G_PARAM_STATIC_STRINGS));
g_object_class_install_property (gobject_class, PROP_VOLUME, g_object_class_install_property (gobject_class, PROP_VOLUME,
g_param_spec_double ("volume", "Volume", "Volume of test signal", 0.0, g_param_spec_double ("volume", "Volume", "Volume of test signal", 0.0,
1.0, 0.8, 1.0, DEFAULT_VOLUME,
G_PARAM_READWRITE | GST_PARAM_CONTROLLABLE | G_PARAM_STATIC_STRINGS)); G_PARAM_READWRITE | GST_PARAM_CONTROLLABLE | G_PARAM_STATIC_STRINGS));
g_object_class_install_property (gobject_class, PROP_IS_LIVE, g_object_class_install_property (gobject_class, PROP_IS_LIVE,
g_param_spec_boolean ("is-live", "Is Live", g_param_spec_boolean ("is-live", "Is Live",
"Whether to act as a live source", FALSE, "Whether to act as a live source", DEFAULT_IS_LIVE,
G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
g_object_class_install_property (G_OBJECT_CLASS (klass), g_object_class_install_property (G_OBJECT_CLASS (klass),
PROP_TIMESTAMP_OFFSET, g_param_spec_int64 ("timestamp-offset", PROP_TIMESTAMP_OFFSET, g_param_spec_int64 ("timestamp-offset",
"Timestamp offset", "Timestamp offset",
"An offset added to timestamps set on buffers (in ns)", G_MININT64, "An offset added to timestamps set on buffers (in ns)", G_MININT64,
G_MAXINT64, 0, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); G_MAXINT64, DEFAULT_TIMESTAMP_OFFSET,
G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
gstbasesrc_class->set_caps = GST_DEBUG_FUNCPTR (gst_audio_test_src_setcaps); gstbasesrc_class->set_caps = GST_DEBUG_FUNCPTR (gst_audio_test_src_setcaps);
gstbasesrc_class->is_seekable = gstbasesrc_class->is_seekable =
GST_DEBUG_FUNCPTR (gst_audio_test_src_is_seekable); GST_DEBUG_FUNCPTR (gst_audio_test_src_is_seekable);
gstbasesrc_class->check_get_range =
GST_DEBUG_FUNCPTR (gst_audio_test_src_check_get_range);
gstbasesrc_class->do_seek = GST_DEBUG_FUNCPTR (gst_audio_test_src_do_seek); gstbasesrc_class->do_seek = GST_DEBUG_FUNCPTR (gst_audio_test_src_do_seek);
gstbasesrc_class->query = GST_DEBUG_FUNCPTR (gst_audio_test_src_query); gstbasesrc_class->query = GST_DEBUG_FUNCPTR (gst_audio_test_src_query);
gstbasesrc_class->get_times = gstbasesrc_class->get_times =
GST_DEBUG_FUNCPTR (gst_audio_test_src_get_times); GST_DEBUG_FUNCPTR (gst_audio_test_src_get_times);
gstbasesrc_class->start = GST_DEBUG_FUNCPTR (gst_audio_test_src_start);
gstbasesrc_class->stop = GST_DEBUG_FUNCPTR (gst_audio_test_src_stop);
gstbasesrc_class->create = GST_DEBUG_FUNCPTR (gst_audio_test_src_create); gstbasesrc_class->create = GST_DEBUG_FUNCPTR (gst_audio_test_src_create);
} }
@ -222,18 +240,19 @@ gst_audio_test_src_init (GstAudioTestSrc * src, GstAudioTestSrcClass * g_class)
src->samplerate = 44100; src->samplerate = 44100;
src->format = GST_AUDIO_TEST_SRC_FORMAT_NONE; src->format = GST_AUDIO_TEST_SRC_FORMAT_NONE;
src->volume = 0.8;
src->freq = 440.0; src->volume = DEFAULT_VOLUME;
src->freq = DEFAULT_FREQ;
/* we operate in time */ /* we operate in time */
gst_base_src_set_format (GST_BASE_SRC (src), GST_FORMAT_TIME); gst_base_src_set_format (GST_BASE_SRC (src), GST_FORMAT_TIME);
gst_base_src_set_live (GST_BASE_SRC (src), FALSE); gst_base_src_set_live (GST_BASE_SRC (src), DEFAULT_IS_LIVE);
src->samples_per_buffer = 1024; src->samples_per_buffer = DEFAULT_SAMPLES_PER_BUFFER;
src->generate_samples_per_buffer = src->samples_per_buffer; src->generate_samples_per_buffer = src->samples_per_buffer;
src->timestamp_offset = G_GINT64_CONSTANT (0); src->timestamp_offset = DEFAULT_TIMESTAMP_OFFSET;
src->wave = GST_AUDIO_TEST_SRC_WAVE_SINE; src->wave = DEFAULT_WAVE;
} }
static void static void
@ -245,6 +264,8 @@ gst_audio_test_src_src_fixate (GstPad * pad, GstCaps * caps)
structure = gst_caps_get_structure (caps, 0); structure = gst_caps_get_structure (caps, 0);
GST_DEBUG_OBJECT (src, "fixating samplerate to %d", src->samplerate);
gst_structure_fixate_field_nearest_int (structure, "rate", src->samplerate); gst_structure_fixate_field_nearest_int (structure, "rate", src->samplerate);
name = gst_structure_get_name (structure); name = gst_structure_get_name (structure);
@ -266,6 +287,8 @@ gst_audio_test_src_setcaps (GstBaseSrc * basesrc, GstCaps * caps)
structure = gst_caps_get_structure (caps, 0); structure = gst_caps_get_structure (caps, 0);
ret = gst_structure_get_int (structure, "rate", &src->samplerate); ret = gst_structure_get_int (structure, "rate", &src->samplerate);
GST_DEBUG_OBJECT (src, "negotiated to samplerate %d", src->samplerate);
name = gst_structure_get_name (structure); name = gst_structure_get_name (structure);
if (strcmp (name, "audio/x-raw-int") == 0) { if (strcmp (name, "audio/x-raw-int") == 0) {
ret &= gst_structure_get_int (structure, "width", &width); ret &= gst_structure_get_int (structure, "width", &width);
@ -277,6 +300,26 @@ gst_audio_test_src_setcaps (GstBaseSrc * basesrc, GstCaps * caps)
GST_AUDIO_TEST_SRC_FORMAT_F64; GST_AUDIO_TEST_SRC_FORMAT_F64;
} }
/* allocate a new buffer suitable for this pad */
switch (src->format) {
case GST_AUDIO_TEST_SRC_FORMAT_S16:
src->sample_size = sizeof (gint16);
break;
case GST_AUDIO_TEST_SRC_FORMAT_S32:
src->sample_size = sizeof (gint32);
break;
case GST_AUDIO_TEST_SRC_FORMAT_F32:
src->sample_size = sizeof (gfloat);
break;
case GST_AUDIO_TEST_SRC_FORMAT_F64:
src->sample_size = sizeof (gdouble);
break;
default:
/* can't really happen */
ret = FALSE;
break;
}
gst_audio_test_src_change_wave (src); gst_audio_test_src_change_wave (src);
return ret; return ret;
@ -676,7 +719,7 @@ gst_audio_test_src_create_tick_##type (GstAudioTestSrc * src, g##type * samples)
if (src->accumulator >= M_PI_M2) \ if (src->accumulator >= M_PI_M2) \
src->accumulator -= M_PI_M2; \ src->accumulator -= M_PI_M2; \
\ \
if ((src->n_samples + i)%src->samplerate < 1600) { \ if ((src->next_sample + i)%src->samplerate < 1600) { \
samples[i] = (g##type) scale * src->wave_table[(gint) (src->accumulator * scl)]; \ samples[i] = (g##type) scale * src->wave_table[(gint) (src->accumulator * scl)]; \
} else { \ } else { \
samples[i] = 0; \ samples[i] = 0; \
@ -784,6 +827,30 @@ gst_audio_test_src_get_times (GstBaseSrc * basesrc, GstBuffer * buffer,
} }
} }
static gboolean
gst_audio_test_src_start (GstBaseSrc * basesrc)
{
GstAudioTestSrc *src = GST_AUDIO_TEST_SRC (basesrc);
src->next_sample = 0;
src->next_byte = 0;
src->next_time = 0;
src->check_seek_stop = FALSE;
src->eos_reached = FALSE;
src->tags_pushed = FALSE;
src->accumulator = 0;
return TRUE;
}
static gboolean
gst_audio_test_src_stop (GstBaseSrc * basesrc)
{
return TRUE;
}
/* seek to time, will be called when we operate in push mode. In pull mode we
* get the requiested byte offset. */
static gboolean static gboolean
gst_audio_test_src_do_seek (GstBaseSrc * basesrc, GstSegment * segment) gst_audio_test_src_do_seek (GstBaseSrc * basesrc, GstSegment * segment)
{ {
@ -794,16 +861,17 @@ gst_audio_test_src_do_seek (GstBaseSrc * basesrc, GstSegment * segment)
time = segment->last_stop; time = segment->last_stop;
/* now move to the time indicated */ /* now move to the time indicated */
src->n_samples = src->next_sample =
gst_util_uint64_scale_int (time, src->samplerate, GST_SECOND); gst_util_uint64_scale_int (time, src->samplerate, GST_SECOND);
src->running_time = src->next_byte = src->next_sample * src->sample_size;
gst_util_uint64_scale_int (src->n_samples, GST_SECOND, src->samplerate); src->next_time =
gst_util_uint64_scale_int (src->next_sample, GST_SECOND, src->samplerate);
g_assert (src->running_time <= time); g_assert (src->next_time <= time);
if (GST_CLOCK_TIME_IS_VALID (segment->stop)) { if (GST_CLOCK_TIME_IS_VALID (segment->stop)) {
time = segment->stop; time = segment->stop;
src->n_samples_stop = gst_util_uint64_scale_int (time, src->samplerate, src->sample_stop = gst_util_uint64_scale_int (time, src->samplerate,
GST_SECOND); GST_SECOND);
src->check_seek_stop = TRUE; src->check_seek_stop = TRUE;
} else { } else {
@ -821,6 +889,13 @@ gst_audio_test_src_is_seekable (GstBaseSrc * basesrc)
return TRUE; return TRUE;
} }
static gboolean
gst_audio_test_src_check_get_range (GstBaseSrc * basesrc)
{
/* if we can operate in pull mode */
return DEFAULT_CAN_ACTIVATE_PULL;
}
static GstFlowReturn static GstFlowReturn
gst_audio_test_src_create (GstBaseSrc * basesrc, guint64 offset, gst_audio_test_src_create (GstBaseSrc * basesrc, guint64 offset,
guint length, GstBuffer ** buffer) guint length, GstBuffer ** buffer)
@ -829,14 +904,11 @@ gst_audio_test_src_create (GstBaseSrc * basesrc, guint64 offset,
GstAudioTestSrc *src; GstAudioTestSrc *src;
GstBuffer *buf; GstBuffer *buf;
GstClockTime next_time; GstClockTime next_time;
gint64 n_samples; gint64 next_sample, next_byte;
gint sample_size; guint bytes, samples;
src = GST_AUDIO_TEST_SRC (basesrc); src = GST_AUDIO_TEST_SRC (basesrc);
if (src->eos_reached)
return GST_FLOW_UNEXPECTED;
/* example for tagging generated data */ /* example for tagging generated data */
if (!src->tags_pushed) { if (!src->tags_pushed) {
GstTagList *taglist; GstTagList *taglist;
@ -852,62 +924,75 @@ gst_audio_test_src_create (GstBaseSrc * basesrc, guint64 offset,
src->tags_pushed = TRUE; src->tags_pushed = TRUE;
} }
if (src->eos_reached)
return GST_FLOW_UNEXPECTED;
/* if no length was given, use our default length in samples otherwise convert
* the length in bytes to samples. */
if (length == -1)
samples = src->samples_per_buffer;
else
samples = length / src->sample_size;
/* if no offset was given, use our next logical byte */
if (offset == -1)
offset = src->next_byte;
/* now see if we are at the byteoffset we think we are */
if (offset != src->next_byte) {
GST_DEBUG_OBJECT (src, "seek to new offset %" G_GUINT64_FORMAT, offset);
/* we have a discont in the expected sample offset, do a 'seek' */
src->next_sample = src->next_byte / src->sample_size;
src->next_time =
gst_util_uint64_scale_int (src->next_sample, GST_SECOND,
src->samplerate);
src->next_byte = offset;
}
/* check for eos */ /* check for eos */
if (src->check_seek_stop && if (src->check_seek_stop &&
(src->n_samples_stop > src->n_samples) && (src->sample_stop > src->next_sample) &&
(src->n_samples_stop < src->n_samples + src->samples_per_buffer) (src->sample_stop < src->next_sample + samples)
) { ) {
/* calculate only partial buffer */ /* calculate only partial buffer */
src->generate_samples_per_buffer = src->n_samples_stop - src->n_samples; src->generate_samples_per_buffer = src->sample_stop - src->next_sample;
n_samples = src->n_samples_stop; next_sample = src->sample_stop;
src->eos_reached = TRUE; src->eos_reached = TRUE;
} else { } else {
/* calculate full buffer */ /* calculate full buffer */
src->generate_samples_per_buffer = src->samples_per_buffer; src->generate_samples_per_buffer = samples;
n_samples = src->n_samples + src->samples_per_buffer; next_sample = src->next_sample + samples;
}
next_time = gst_util_uint64_scale (n_samples, GST_SECOND,
(guint64) src->samplerate);
/* allocate a new buffer suitable for this pad */
switch (src->format) {
case GST_AUDIO_TEST_SRC_FORMAT_S16:
sample_size = sizeof (gint16);
break;
case GST_AUDIO_TEST_SRC_FORMAT_S32:
sample_size = sizeof (gint32);
break;
case GST_AUDIO_TEST_SRC_FORMAT_F32:
sample_size = sizeof (gfloat);
break;
case GST_AUDIO_TEST_SRC_FORMAT_F64:
sample_size = sizeof (gdouble);
break;
default:
sample_size = -1;
GST_ELEMENT_ERROR (src, CORE, NEGOTIATION, (NULL),
("format wasn't negotiated before get function"));
return GST_FLOW_NOT_NEGOTIATED;
break;
} }
if ((res = gst_pad_alloc_buffer (basesrc->srcpad, src->n_samples, bytes = src->generate_samples_per_buffer * src->sample_size;
src->generate_samples_per_buffer * sample_size,
GST_PAD_CAPS (basesrc->srcpad), &buf)) != GST_FLOW_OK) { if ((res = gst_pad_alloc_buffer (basesrc->srcpad, src->next_sample,
bytes, GST_PAD_CAPS (basesrc->srcpad), &buf)) != GST_FLOW_OK) {
return res; return res;
} }
GST_BUFFER_TIMESTAMP (buf) = src->timestamp_offset + src->running_time; next_byte = src->next_byte + bytes;
GST_BUFFER_OFFSET_END (buf) = n_samples; next_time = gst_util_uint64_scale_int (next_sample, GST_SECOND,
GST_BUFFER_DURATION (buf) = next_time - src->running_time; src->samplerate);
gst_object_sync_values (G_OBJECT (src), src->running_time); GST_LOG_OBJECT (src, "samplerate %d", src->samplerate);
GST_LOG_OBJECT (src, "next_sample %" G_GINT64_FORMAT ", ts %" GST_TIME_FORMAT,
next_sample, GST_TIME_ARGS (next_time));
src->running_time = next_time; GST_BUFFER_TIMESTAMP (buf) = src->timestamp_offset + src->next_time;
src->n_samples = n_samples; GST_BUFFER_OFFSET (buf) = src->next_sample;
GST_BUFFER_OFFSET_END (buf) = next_sample;
GST_BUFFER_DURATION (buf) = next_time - src->next_time;
gst_object_sync_values (G_OBJECT (src), src->next_time);
src->next_time = next_time;
src->next_sample = next_sample;
src->next_byte = next_byte;
GST_LOG_OBJECT (src, "generating %u samples at ts %" GST_TIME_FORMAT, GST_LOG_OBJECT (src, "generating %u samples at ts %" GST_TIME_FORMAT,
length, GST_TIME_ARGS (GST_BUFFER_TIMESTAMP (buf))); src->generate_samples_per_buffer,
GST_TIME_ARGS (GST_BUFFER_TIMESTAMP (buf)));
src->process (src, GST_BUFFER_DATA (buf)); src->process (src, GST_BUFFER_DATA (buf));

View file

@ -107,14 +107,16 @@ struct _GstAudioTestSrc {
/* audio parameters */ /* audio parameters */
gint samplerate; gint samplerate;
gint samples_per_buffer; gint samples_per_buffer;
gint sample_size;
GstAudioTestSrcFormat format; GstAudioTestSrcFormat format;
/*< private >*/ /*< private >*/
gboolean tags_pushed; /* send tags just once ? */ gboolean tags_pushed; /* send tags just once ? */
GstClockTimeDiff timestamp_offset; /* base offset */ GstClockTimeDiff timestamp_offset; /* base offset */
GstClockTime running_time; /* total running time */ GstClockTime next_time; /* next timestamp */
gint64 n_samples; /* total samples sent */ gint64 next_sample; /* next sample to send */
gint64 n_samples_stop; gint64 next_byte; /* next byte to send */
gint64 sample_stop;
gboolean check_seek_stop; gboolean check_seek_stop;
gboolean eos_reached; gboolean eos_reached;
gint generate_samples_per_buffer; /* used to generate a partial buffer */ gint generate_samples_per_buffer; /* used to generate a partial buffer */