gst/audiotestsrc/gstaudiotestsrc.*: fixed typo, added pink noise

Original commit message from CVS:
* gst/audiotestsrc/gstaudiotestsrc.c:
(gst_audiostestsrc_wave_get_type), (gst_audiotestsrc_class_init),
(gst_audiotestsrc_init), (gst_audiotestsrc_create_sine),
(gst_audiotestsrc_create_square), (gst_audiotestsrc_create_saw),
(gst_audiotestsrc_create_triangle),
(gst_audiotestsrc_create_silence),
(gst_audiotestsrc_create_white_noise),
(gst_audiotestsrc_init_pink_noise),
(gst_audiotestsrc_generate_pink_noise_value),
(gst_audiotestsrc_create_pink_noise),
(gst_audiotestsrc_change_wave):
* gst/audiotestsrc/gstaudiotestsrc.h:
fixed typo, added pink noise
This commit is contained in:
Stefan Kost 2005-10-09 20:47:31 +00:00
parent 3869244aca
commit 7f3f034d44
3 changed files with 121 additions and 3 deletions

View file

@ -1,3 +1,19 @@
2005-10-09 Stefan Kost <ensonic@users.sf.net>
* gst/audiotestsrc/gstaudiotestsrc.c:
(gst_audiostestsrc_wave_get_type), (gst_audiotestsrc_class_init),
(gst_audiotestsrc_init), (gst_audiotestsrc_create_sine),
(gst_audiotestsrc_create_square), (gst_audiotestsrc_create_saw),
(gst_audiotestsrc_create_triangle),
(gst_audiotestsrc_create_silence),
(gst_audiotestsrc_create_white_noise),
(gst_audiotestsrc_init_pink_noise),
(gst_audiotestsrc_generate_pink_noise_value),
(gst_audiotestsrc_create_pink_noise),
(gst_audiotestsrc_change_wave):
* gst/audiotestsrc/gstaudiotestsrc.h:
fixed typo, added pink noise
2005-10-09 Tim-Philipp Müller <tim at centricular dot net>
* gst/typefind/gsttypefindfunctions.c: (wavpack_type_find),

View file

@ -96,9 +96,10 @@ gst_audiostestsrc_wave_get_type (void)
{GST_AUDIOTESTSRC_WAVE_SINE, "0", "Sine"},
{GST_AUDIOTESTSRC_WAVE_SQUARE, "1", "Square"},
{GST_AUDIOTESTSRC_WAVE_SAW, "2", "Saw"},
{GST_AUDIOTESTSRC_WAVE_TRIANGLE, "3", "Trinagle"},
{GST_AUDIOTESTSRC_WAVE_TRIANGLE, "3", "Triangle"},
{GST_AUDIOTESTSRC_WAVE_SILENCE, "4", "Silence"},
{GST_AUDIOTESTSRC_WAVE_WHITE_NOISE, "5", "White noise"},
{GST_AUDIOTESTSRC_WAVE_PINK_NOISE, "6", "Pink noise"},
{0, NULL, NULL},
};
@ -421,6 +422,86 @@ gst_audiotestsrc_create_white_noise (GstAudioTestSrc * src, gint16 * samples)
}
}
/* pink noise calculation is based on
* http://www.firstpr.com.au/dsp/pink-noise/phil_burk_19990905_patest_pink.c
* which has been released under public domain
* Many thanks Phil!
*/
static void
gst_audiotestsrc_init_pink_noise (GstAudioTestSrc * src)
{
gint i;
gint num_rows = 12; /* arbitrary: 1 .. PINK_MAX_RANDOM_ROWS */
glong pmax;
src->pink.index = 0;
src->pink.index_mask = (1 << num_rows) - 1;
/* calculate maximum possible signed random value.
* Extra 1 for white noise always added. */
pmax = (num_rows + 1) * (1 << (PINK_RANDOM_BITS - 1));
src->pink.scalar = 1.0f / pmax;
/* Initialize rows. */
for (i = 0; i < num_rows; i++)
src->pink.rows[i] = 0;
src->pink.running_sum = 0;
}
/* Generate Pink noise values between -1.0 and +1.0 */
static gfloat
gst_audiotestsrc_generate_pink_noise_value (GstPinkNoise * pink)
{
glong new_random;
glong sum;
/* Increment and mask index. */
pink->index = (pink->index + 1) & pink->index_mask;
/* If index is zero, don't update any random values. */
if (pink->index != 0) {
/* Determine how many trailing zeros in PinkIndex. */
/* This algorithm will hang if n==0 so test first. */
gint num_zeros = 0;
gint n = pink->index;
while ((n & 1) == 0) {
n = n >> 1;
num_zeros++;
}
/* Replace the indexed ROWS random value.
* Subtract and add back to RunningSum instead of adding all the random
* values together. Only one changes each time.
*/
pink->running_sum -= pink->rows[num_zeros];
//new_random = ((glong)GenerateRandomNumber()) >> PINK_RANDOM_SHIFT;
new_random = 32768.0 - (65536.0 * (gulong) rand () / (RAND_MAX + 1.0));
pink->running_sum += new_random;
pink->rows[num_zeros] = new_random;
}
/* Add extra white noise value. */
new_random = 32768.0 - (65536.0 * (gulong) rand () / (RAND_MAX + 1.0));
sum = pink->running_sum + new_random;
/* Scale to range of -1.0 to 0.9999. */
return (pink->scalar * sum);
}
static void
gst_audiotestsrc_create_pink_noise (GstAudioTestSrc * src, gint16 * samples)
{
gint i;
gdouble amp;
amp = src->volume * 32767.0;
for (i = 0; i < src->samples_per_buffer; i++) {
samples[i] =
(gint16) (gst_audiotestsrc_generate_pink_noise_value (&src->pink) *
amp);
}
}
static void
gst_audiotestsrc_change_wave (GstAudioTestSrc * src)
{
@ -443,6 +524,10 @@ gst_audiotestsrc_change_wave (GstAudioTestSrc * src)
case GST_AUDIOTESTSRC_WAVE_WHITE_NOISE:
src->process = gst_audiotestsrc_create_white_noise;
break;
case GST_AUDIOTESTSRC_WAVE_PINK_NOISE:
gst_audiotestsrc_init_pink_noise (src);
src->process = gst_audiotestsrc_create_pink_noise;
break;
default:
GST_ERROR ("invalid wave-form");
break;

View file

@ -49,8 +49,21 @@ typedef enum {
GST_AUDIOTESTSRC_WAVE_TRIANGLE,
GST_AUDIOTESTSRC_WAVE_SILENCE,
GST_AUDIOTESTSRC_WAVE_WHITE_NOISE,
GST_AUDIOTESTSRC_WAVE_PINK_NOISE,
} GstAudioTestSrcWaves;
#define PINK_MAX_RANDOM_ROWS (30)
#define PINK_RANDOM_BITS (16)
#define PINK_RANDOM_SHIFT ((sizeof(long)*8)-PINK_RANDOM_BITS)
typedef struct {
glong rows[PINK_MAX_RANDOM_ROWS];
glong running_sum; /* Used to optimize summing of generators. */
gint index; /* Incremented each sample. */
gint index_mask; /* Index wrapped by ANDing with this mask. */
gfloat scalar; /* Used to scale within range of -1.0 to +1.0 */
} GstPinkNoise;
typedef struct _GstAudioTestSrc GstAudioTestSrc;
typedef struct _GstAudioTestSrcClass GstAudioTestSrcClass;
@ -63,7 +76,7 @@ struct _GstAudioTestSrc {
GstAudioTestSrcWaves wave;
gdouble volume;
gdouble freq;
/* audio parameters */
gint samplerate;
@ -78,6 +91,11 @@ struct _GstAudioTestSrc {
GstClockID clock_id;
GstClockTimeDiff timestamp_offset;
/* < private > */
/* waveform specific context data */
GstPinkNoise pink;
};
struct _GstAudioTestSrcClass {
@ -89,5 +107,4 @@ gboolean gst_audiotestsrc_factory_init (GstElementFactory *factory);
G_END_DECLS
#endif /* __GST_AUDIOTESTSRC_H__ */