audiotestsrc: support more than just one channel

This commit is contained in:
Tim-Philipp Müller 2009-05-01 01:03:06 +01:00
parent ab75db1653
commit 72c5884f4a
2 changed files with 65 additions and 36 deletions

View file

@ -101,18 +101,18 @@ static GstStaticPadTemplate gst_audio_test_src_src_template =
"width = (int) 16, "
"depth = (int) 16, "
"rate = (int) [ 1, MAX ], "
"channels = (int) 1; "
"channels = (int) [ 1, 2 ]; "
"audio/x-raw-int, "
"endianness = (int) BYTE_ORDER, "
"signed = (boolean) true, "
"width = (int) 32, "
"depth = (int) 32,"
"rate = (int) [ 1, MAX ], "
"channels = (int) 1; "
"channels = (int) [ 1, 2 ]; "
"audio/x-raw-float, "
"endianness = (int) BYTE_ORDER, "
"width = (int) { 32, 64 }, "
"rate = (int) [ 1, MAX ], " "channels = (int) 1")
"rate = (int) [ 1, MAX ], " "channels = (int) [ 1, 2 ]")
);
@ -286,6 +286,9 @@ gst_audio_test_src_src_fixate (GstPad * pad, GstCaps * caps)
gst_structure_fixate_field_nearest_int (structure, "width", 32);
else if (strcmp (name, "audio/x-raw-float") == 0)
gst_structure_fixate_field_nearest_int (structure, "width", 64);
/* fixate to mono unless downstream requires stereo, for backwards compat */
gst_structure_fixate_field_nearest_int (structure, "channels", 1);
}
static gboolean
@ -333,6 +336,9 @@ gst_audio_test_src_setcaps (GstBaseSrc * basesrc, GstCaps * caps)
break;
}
ret &= gst_structure_get_int (structure, "channels", &src->channels);
GST_DEBUG_OBJECT (src, "negotiated to %d channels", src->channels);
gst_audio_test_src_change_wave (src);
return ret;
@ -407,18 +413,21 @@ error:
static void \
gst_audio_test_src_create_sine_##type (GstAudioTestSrc * src, g##type * samples) \
{ \
gint i; \
gint i, c; \
gdouble step, amp; \
\
step = M_PI_M2 * src->freq / src->samplerate; \
amp = src->volume * scale; \
\
for (i = 0; i < src->generate_samples_per_buffer; i++) { \
i = 0; \
while (i < (src->generate_samples_per_buffer * src->channels)) { \
src->accumulator += step; \
if (src->accumulator >= M_PI_M2) \
src->accumulator -= M_PI_M2; \
\
samples[i] = (g##type) (sin (src->accumulator) * amp); \
for (c = 0; c < src->channels; ++c) { \
samples[i++] = (g##type) (sin (src->accumulator) * amp); \
} \
} \
}
@ -438,18 +447,21 @@ static ProcessFunc sine_funcs[] = {
static void \
gst_audio_test_src_create_square_##type (GstAudioTestSrc * src, g##type * samples) \
{ \
gint i; \
gint i, c; \
gdouble step, amp; \
\
step = M_PI_M2 * src->freq / src->samplerate; \
amp = src->volume * scale; \
\
for (i = 0; i < src->generate_samples_per_buffer; i++) { \
i = 0; \
while (i < (src->generate_samples_per_buffer * src->channels)) { \
src->accumulator += step; \
if (src->accumulator >= M_PI_M2) \
src->accumulator -= M_PI_M2; \
\
samples[i] = (g##type) ((src->accumulator < M_PI) ? amp : -amp); \
for (c = 0; c < src->channels; ++c) { \
samples[i++] = (g##type) ((src->accumulator < M_PI) ? amp : -amp); \
} \
} \
}
@ -469,21 +481,24 @@ static ProcessFunc square_funcs[] = {
static void \
gst_audio_test_src_create_saw_##type (GstAudioTestSrc * src, g##type * samples) \
{ \
gint i; \
gint i, c; \
gdouble step, amp; \
\
step = M_PI_M2 * src->freq / src->samplerate; \
amp = (src->volume * scale) / M_PI; \
\
for (i = 0; i < src->generate_samples_per_buffer; i++) { \
i = 0; \
while (i < (src->generate_samples_per_buffer * src->channels)) { \
src->accumulator += step; \
if (src->accumulator >= M_PI_M2) \
src->accumulator -= M_PI_M2; \
\
if (src->accumulator < M_PI) { \
samples[i] = (g##type) (src->accumulator * amp); \
for (c = 0; c < src->channels; ++c) \
samples[i++] = (g##type) (src->accumulator * amp); \
} else { \
samples[i] = (g##type) ((M_PI_M2 - src->accumulator) * -amp); \
for (c = 0; c < src->channels; ++c) \
samples[i++] = (g##type) ((M_PI_M2 - src->accumulator) * -amp); \
} \
} \
}
@ -504,23 +519,27 @@ static ProcessFunc saw_funcs[] = {
static void \
gst_audio_test_src_create_triangle_##type (GstAudioTestSrc * src, g##type * samples) \
{ \
gint i; \
gint i, c; \
gdouble step, amp; \
\
step = M_PI_M2 * src->freq / src->samplerate; \
amp = (src->volume * scale) / M_PI_2; \
\
for (i = 0; i < src->generate_samples_per_buffer; i++) { \
i = 0; \
while (i < (src->generate_samples_per_buffer * src->channels)) { \
src->accumulator += step; \
if (src->accumulator >= M_PI_M2) \
src->accumulator -= M_PI_M2; \
\
if (src->accumulator < (M_PI * 0.5)) { \
samples[i] = (g##type) (src->accumulator * amp); \
for (c = 0; c < src->channels; ++c) \
samples[i++] = (g##type) (src->accumulator * amp); \
} else if (src->accumulator < (M_PI * 1.5)) { \
samples[i] = (g##type) ((src->accumulator - M_PI) * -amp); \
for (c = 0; c < src->channels; ++c) \
samples[i++] = (g##type) ((src->accumulator - M_PI) * -amp); \
} else { \
samples[i] = (g##type) ((M_PI_M2 - src->accumulator) * -amp); \
for (c = 0; c < src->channels; ++c) \
samples[i++] = (g##type) ((M_PI_M2 - src->accumulator) * -amp); \
} \
} \
}
@ -541,7 +560,7 @@ static ProcessFunc triangle_funcs[] = {
static void \
gst_audio_test_src_create_silence_##type (GstAudioTestSrc * src, g##type * samples) \
{ \
memset (samples, 0, src->generate_samples_per_buffer * sizeof (g##type)); \
memset (samples, 0, src->generate_samples_per_buffer * sizeof (g##type) * src->channels); \
}
DEFINE_SILENCE (int16);
@ -560,11 +579,13 @@ static ProcessFunc silence_funcs[] = {
static void \
gst_audio_test_src_create_white_noise_##type (GstAudioTestSrc * src, g##type * samples) \
{ \
gint i; \
gint i, c; \
gdouble amp = (src->volume * scale); \
\
for (i = 0; i < src->generate_samples_per_buffer; i++) { \
samples[i] = (g##type) (amp * g_random_double_range (-1.0, 1.0)); \
i = 0; \
while (i < (src->generate_samples_per_buffer * src->channels)) { \
for (c = 0; c < src->channels; ++c) \
samples[i++] = (g##type) (amp * g_random_double_range (-1.0, 1.0)); \
} \
}
@ -648,16 +669,19 @@ gst_audio_test_src_generate_pink_noise_value (GstPinkNoise * pink)
static void \
gst_audio_test_src_create_pink_noise_##type (GstAudioTestSrc * src, g##type * samples) \
{ \
gint i; \
gint i, c; \
gdouble amp; \
\
amp = src->volume * scale; \
\
for (i = 0; i < src->generate_samples_per_buffer; i++) { \
samples[i] = \
i = 0; \
while (i < (src->generate_samples_per_buffer * src->channels)) { \
for (c = 0; c < src->channels; ++c) { \
samples[i++] = \
(g##type) (gst_audio_test_src_generate_pink_noise_value (&src->pink) * \
amp); \
} \
} \
}
DEFINE_PINK (int16, 32767.0);
@ -690,18 +714,20 @@ gst_audio_test_src_init_sine_table (GstAudioTestSrc * src)
static void \
gst_audio_test_src_create_sine_table_##type (GstAudioTestSrc * src, g##type * samples) \
{ \
gint i; \
gint i, c; \
gdouble step, scl; \
\
step = M_PI_M2 * src->freq / src->samplerate; \
scl = 1024.0 / M_PI_M2; \
\
for (i = 0; i < src->generate_samples_per_buffer; i++) { \
i = 0; \
while (i < (src->generate_samples_per_buffer * src->channels)) { \
src->accumulator += step; \
if (src->accumulator >= M_PI_M2) \
src->accumulator -= M_PI_M2; \
\
samples[i] = (g##type) scale * src->wave_table[(gint) (src->accumulator * scl)]; \
for (c = 0; c < src->channels; ++c) \
samples[i++] = (g##type) scale * src->wave_table[(gint) (src->accumulator * scl)]; \
} \
}
@ -721,7 +747,7 @@ static ProcessFunc sine_table_funcs[] = {
static void \
gst_audio_test_src_create_tick_##type (GstAudioTestSrc * src, g##type * samples) \
{ \
gint i; \
gint i, c; \
gdouble step, scl; \
\
step = M_PI_M2 * src->freq / src->samplerate; \
@ -733,9 +759,11 @@ gst_audio_test_src_create_tick_##type (GstAudioTestSrc * src, g##type * samples)
src->accumulator -= M_PI_M2; \
\
if ((src->next_sample + i)%src->samplerate < 1600) { \
samples[i] = (g##type) scale * src->wave_table[(gint) (src->accumulator * scl)]; \
for (c = 0; c < src->channels; ++c) \
samples[(i * src->channels) + c] = (g##type) scale * src->wave_table[(gint) (src->accumulator * scl)]; \
} else { \
samples[i] = 0; \
for (c = 0; c < src->channels; ++c) \
samples[(i * src->channels) + c] = 0; \
} \
} \
}
@ -863,7 +891,7 @@ gst_audio_test_src_stop (GstBaseSrc * basesrc)
}
/* seek to time, will be called when we operate in push mode. In pull mode we
* get the requiested byte offset. */
* get the requested byte offset. */
static gboolean
gst_audio_test_src_do_seek (GstBaseSrc * basesrc, GstSegment * segment)
{
@ -876,7 +904,7 @@ gst_audio_test_src_do_seek (GstBaseSrc * basesrc, GstSegment * segment)
/* now move to the time indicated */
src->next_sample =
gst_util_uint64_scale_int (time, src->samplerate, GST_SECOND);
src->next_byte = src->next_sample * src->sample_size;
src->next_byte = src->next_sample * src->sample_size * src->channels;
src->next_time =
gst_util_uint64_scale_int (src->next_sample, GST_SECOND, src->samplerate);
@ -949,7 +977,7 @@ gst_audio_test_src_create (GstBaseSrc * basesrc, guint64 offset,
if (length == -1)
samples = src->samples_per_buffer;
else
samples = length / src->sample_size;
samples = length / (src->sample_size * src->channels);
/* if no offset was given, use our next logical byte */
if (offset == -1)
@ -959,7 +987,7 @@ gst_audio_test_src_create (GstBaseSrc * basesrc, guint64 offset,
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_sample = src->next_byte / (src->sample_size * src->channels);
src->next_time =
gst_util_uint64_scale_int (src->next_sample, GST_SECOND,
src->samplerate);
@ -981,7 +1009,7 @@ gst_audio_test_src_create (GstBaseSrc * basesrc, guint64 offset,
next_sample = src->next_sample + samples;
}
bytes = src->generate_samples_per_buffer * src->sample_size;
bytes = src->generate_samples_per_buffer * src->sample_size * src->channels;
if ((res = gst_pad_alloc_buffer (basesrc->srcpad, src->next_sample,
bytes, GST_PAD_CAPS (basesrc->srcpad), &buf)) != GST_FLOW_OK) {

View file

@ -105,6 +105,7 @@ struct _GstAudioTestSrc {
gdouble freq;
/* audio parameters */
gint channels;
gint samplerate;
gint samples_per_buffer;
gint sample_size;