mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2025-01-11 09:55:36 +00:00
audiotestsrc: support more than just one channel
This commit is contained in:
parent
ab75db1653
commit
72c5884f4a
2 changed files with 65 additions and 36 deletions
|
@ -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,15 +669,18 @@ 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); \
|
||||
} \
|
||||
} \
|
||||
}
|
||||
|
||||
|
@ -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) {
|
||||
|
|
|
@ -105,6 +105,7 @@ struct _GstAudioTestSrc {
|
|||
gdouble freq;
|
||||
|
||||
/* audio parameters */
|
||||
gint channels;
|
||||
gint samplerate;
|
||||
gint samples_per_buffer;
|
||||
gint sample_size;
|
||||
|
|
Loading…
Reference in a new issue