gst_plugins_base/gst/audiotestsrc/gstaudiotestsrc.c
branchRCL_3
changeset 30 7e817e7e631c
parent 29 567bb019e3e3
equal deleted inserted replaced
29:567bb019e3e3 30:7e817e7e631c
    17  * Boston, MA 02111-1307, USA.
    17  * Boston, MA 02111-1307, USA.
    18  */
    18  */
    19 /**
    19 /**
    20  * SECTION:element-audiotestsrc
    20  * SECTION:element-audiotestsrc
    21  *
    21  *
       
    22  * <refsect2>
       
    23  * <para>
    22  * AudioTestSrc can be used to generate basic audio signals. It support several
    24  * AudioTestSrc can be used to generate basic audio signals. It support several
    23  * different waveforms and allows to set the base frequency and volume.
    25  * different waveforms and allows you to set the base frequency and volume.
    24  *
    26  * </para>
    25  * <refsect2>
       
    26  * <title>Example launch line</title>
    27  * <title>Example launch line</title>
    27  * |[
    28  * <para>
       
    29  * <programlisting>
    28  * gst-launch audiotestsrc ! audioconvert ! alsasink
    30  * gst-launch audiotestsrc ! audioconvert ! alsasink
    29  * ]| This pipeline produces a sine with default frequency, 440 Hz, and the
    31  * </programlisting>
    30  * default volume, 0.8 (relative to a maximum 1.0).
    32  * This pipeline produces a sine with default frequency (mid-C) and volume.
    31  * |[
    33  * </para>
       
    34  * <para>
       
    35  * <programlisting>
    32  * gst-launch audiotestsrc wave=2 freq=200 ! audioconvert ! tee name=t ! queue ! alsasink t. ! queue ! libvisual_lv_scope ! ffmpegcolorspace ! xvimagesink
    36  * gst-launch audiotestsrc wave=2 freq=200 ! audioconvert ! tee name=t ! queue ! alsasink t. ! queue ! libvisual_lv_scope ! ffmpegcolorspace ! xvimagesink
    33  * ]| In this example a saw wave is generated. The wave is shown using a
    37  * </programlisting>
       
    38  * In this example a saw wave is generated. The wave is shown using a
    34  * scope visualizer from libvisual, allowing you to visually verify that
    39  * scope visualizer from libvisual, allowing you to visually verify that
    35  * the saw wave is correct.
    40  * the saw wave is correct.
       
    41  * </para>
    36  * </refsect2>
    42  * </refsect2>
    37  */
    43  */
    38 
    44 
    39 #ifdef HAVE_CONFIG_H
    45 #ifdef HAVE_CONFIG_H
    40 #include "config.h"
    46 #include "config.h"
    42 
    48 
    43 #include <math.h>
    49 #include <math.h>
    44 #include <stdlib.h>
    50 #include <stdlib.h>
    45 #include <string.h>
    51 #include <string.h>
    46 #include <gst/controller/gstcontroller.h>
    52 #include <gst/controller/gstcontroller.h>
    47 
    53 #include <glib_global.h>
    48 #include "gstaudiotestsrc.h"
    54 #include "gstaudiotestsrc.h"
    49 
    55 
    50 
    56 
    51 #ifndef M_PI
    57 #ifndef M_PI
    52 #define M_PI  3.14159265358979323846
    58 #define M_PI  3.14159265358979323846
    65 GST_ELEMENT_DETAILS ("Audio test source",
    71 GST_ELEMENT_DETAILS ("Audio test source",
    66     "Source/Audio",
    72     "Source/Audio",
    67     "Creates audio test signals of given frequency and volume",
    73     "Creates audio test signals of given frequency and volume",
    68     "Stefan Kost <ensonic@users.sf.net>");
    74     "Stefan Kost <ensonic@users.sf.net>");
    69 
    75 
    70 #define DEFAULT_SAMPLES_PER_BUFFER   1024
       
    71 #define DEFAULT_WAVE                 GST_AUDIO_TEST_SRC_WAVE_SINE
       
    72 #define DEFAULT_FREQ                 440.0
       
    73 #define DEFAULT_VOLUME               0.8
       
    74 #define DEFAULT_IS_LIVE              FALSE
       
    75 #define DEFAULT_TIMESTAMP_OFFSET     G_GINT64_CONSTANT (0)
       
    76 #define DEFAULT_CAN_ACTIVATE_PUSH    TRUE
       
    77 #define DEFAULT_CAN_ACTIVATE_PULL    FALSE
       
    78 
    76 
    79 enum
    77 enum
    80 {
    78 {
    81   PROP_0,
    79   PROP_0,
    82   PROP_SAMPLES_PER_BUFFER,
    80   PROP_SAMPLES_PER_BUFFER,
    83   PROP_WAVE,
    81   PROP_WAVE,
    84   PROP_FREQ,
    82   PROP_FREQ,
    85   PROP_VOLUME,
    83   PROP_VOLUME,
    86   PROP_IS_LIVE,
    84   PROP_IS_LIVE,
    87   PROP_TIMESTAMP_OFFSET,
    85   PROP_TIMESTAMP_OFFSET,
    88   PROP_CAN_ACTIVATE_PUSH,
       
    89   PROP_CAN_ACTIVATE_PULL,
       
    90   PROP_LAST
       
    91 };
    86 };
    92 
    87 
    93 
    88 
    94 static GstStaticPadTemplate gst_audio_test_src_src_template =
    89 static GstStaticPadTemplate gst_audio_test_src_src_template =
    95     GST_STATIC_PAD_TEMPLATE ("src",
    90     GST_STATIC_PAD_TEMPLATE ("src",
    99         "endianness = (int) BYTE_ORDER, "
    94         "endianness = (int) BYTE_ORDER, "
   100         "signed = (boolean) true, "
    95         "signed = (boolean) true, "
   101         "width = (int) 16, "
    96         "width = (int) 16, "
   102         "depth = (int) 16, "
    97         "depth = (int) 16, "
   103         "rate = (int) [ 1, MAX ], "
    98         "rate = (int) [ 1, MAX ], "
   104         "channels = (int) [ 1, 2 ]; "
    99         "channels = (int) 1; "
   105         "audio/x-raw-int, "
   100         "audio/x-raw-int, "
   106         "endianness = (int) BYTE_ORDER, "
   101         "endianness = (int) BYTE_ORDER, "
   107         "signed = (boolean) true, "
   102         "signed = (boolean) true, "
   108         "width = (int) 32, "
   103         "width = (int) 32, "
   109         "depth = (int) 32,"
   104         "depth = (int) 32,"
   110         "rate = (int) [ 1, MAX ], "
   105         "rate = (int) [ 1, MAX ], "
   111         "channels = (int) [ 1, 2 ]; "
   106         "channels = (int) 1; "
   112         "audio/x-raw-float, "
   107         "audio/x-raw-float, "
   113         "endianness = (int) BYTE_ORDER, "
   108         "endianness = (int) BYTE_ORDER, "
   114         "width = (int) { 32, 64 }, "
   109         "width = (int) { 32, 64 }, "
   115         "rate = (int) [ 1, MAX ], " "channels = (int) [ 1, 2 ]")
   110         "rate = (int) [ 1, MAX ], " "channels = (int) 1")
   116     );
   111     );
   117 
   112 
   118 
   113 
   119 GST_BOILERPLATE (GstAudioTestSrc, gst_audio_test_src, GstBaseSrc,
   114 GST_BOILERPLATE (GstAudioTestSrc, gst_audio_test_src, GstBaseSrc,
   120     GST_TYPE_BASE_SRC);
   115     GST_TYPE_BASE_SRC);
   128     {GST_AUDIO_TEST_SRC_WAVE_SINE, "Sine", "sine"},
   123     {GST_AUDIO_TEST_SRC_WAVE_SINE, "Sine", "sine"},
   129     {GST_AUDIO_TEST_SRC_WAVE_SQUARE, "Square", "square"},
   124     {GST_AUDIO_TEST_SRC_WAVE_SQUARE, "Square", "square"},
   130     {GST_AUDIO_TEST_SRC_WAVE_SAW, "Saw", "saw"},
   125     {GST_AUDIO_TEST_SRC_WAVE_SAW, "Saw", "saw"},
   131     {GST_AUDIO_TEST_SRC_WAVE_TRIANGLE, "Triangle", "triangle"},
   126     {GST_AUDIO_TEST_SRC_WAVE_TRIANGLE, "Triangle", "triangle"},
   132     {GST_AUDIO_TEST_SRC_WAVE_SILENCE, "Silence", "silence"},
   127     {GST_AUDIO_TEST_SRC_WAVE_SILENCE, "Silence", "silence"},
   133     {GST_AUDIO_TEST_SRC_WAVE_WHITE_NOISE, "White uniform noise", "white-noise"},
   128     {GST_AUDIO_TEST_SRC_WAVE_WHITE_NOISE, "White noise", "white-noise"},
   134     {GST_AUDIO_TEST_SRC_WAVE_PINK_NOISE, "Pink noise", "pink-noise"},
   129     {GST_AUDIO_TEST_SRC_WAVE_PINK_NOISE, "Pink noise", "pink-noise"},
   135     {GST_AUDIO_TEST_SRC_WAVE_SINE_TAB, "Sine table", "sine-table"},
   130     {GST_AUDIO_TEST_SRC_WAVE_SINE_TAB, "Sine table", "sine table"},
   136     {GST_AUDIO_TEST_SRC_WAVE_TICKS, "Periodic Ticks", "ticks"},
       
   137     {GST_AUDIO_TEST_SRC_WAVE_GAUSSIAN_WHITE_NOISE, "White Gaussian noise",
       
   138         "gaussian-noise"},
       
   139     {0, NULL, NULL},
   131     {0, NULL, NULL},
   140   };
   132   };
   141 
   133 
   142   if (G_UNLIKELY (audiostestsrc_wave_type == 0)) {
   134   if (G_UNLIKELY (audiostestsrc_wave_type == 0)) {
   143     audiostestsrc_wave_type = g_enum_register_static ("GstAudioTestSrcWave",
   135     audiostestsrc_wave_type = g_enum_register_static ("GstAudioTestSrcWave",
   154 static gboolean gst_audio_test_src_setcaps (GstBaseSrc * basesrc,
   146 static gboolean gst_audio_test_src_setcaps (GstBaseSrc * basesrc,
   155     GstCaps * caps);
   147     GstCaps * caps);
   156 static void gst_audio_test_src_src_fixate (GstPad * pad, GstCaps * caps);
   148 static void gst_audio_test_src_src_fixate (GstPad * pad, GstCaps * caps);
   157 
   149 
   158 static gboolean gst_audio_test_src_is_seekable (GstBaseSrc * basesrc);
   150 static gboolean gst_audio_test_src_is_seekable (GstBaseSrc * basesrc);
   159 static gboolean gst_audio_test_src_check_get_range (GstBaseSrc * basesrc);
       
   160 static gboolean gst_audio_test_src_do_seek (GstBaseSrc * basesrc,
   151 static gboolean gst_audio_test_src_do_seek (GstBaseSrc * basesrc,
   161     GstSegment * segment);
   152     GstSegment * segment);
   162 static gboolean gst_audio_test_src_query (GstBaseSrc * basesrc,
   153 static gboolean gst_audio_test_src_query (GstBaseSrc * basesrc,
   163     GstQuery * query);
   154     GstQuery * query);
   164 
   155 
   165 static void gst_audio_test_src_change_wave (GstAudioTestSrc * src);
   156 static void gst_audio_test_src_change_wave (GstAudioTestSrc * src);
   166 
   157 
   167 static void gst_audio_test_src_get_times (GstBaseSrc * basesrc,
   158 static void gst_audio_test_src_get_times (GstBaseSrc * basesrc,
   168     GstBuffer * buffer, GstClockTime * start, GstClockTime * end);
   159     GstBuffer * buffer, GstClockTime * start, GstClockTime * end);
   169 static gboolean gst_audio_test_src_start (GstBaseSrc * basesrc);
       
   170 static gboolean gst_audio_test_src_stop (GstBaseSrc * basesrc);
       
   171 static GstFlowReturn gst_audio_test_src_create (GstBaseSrc * basesrc,
   160 static GstFlowReturn gst_audio_test_src_create (GstBaseSrc * basesrc,
   172     guint64 offset, guint length, GstBuffer ** buffer);
   161     guint64 offset, guint length, GstBuffer ** buffer);
   173 
   162 
   174 
   163 
   175 static void
   164 static void
   195   gobject_class->get_property = gst_audio_test_src_get_property;
   184   gobject_class->get_property = gst_audio_test_src_get_property;
   196 
   185 
   197   g_object_class_install_property (gobject_class, PROP_SAMPLES_PER_BUFFER,
   186   g_object_class_install_property (gobject_class, PROP_SAMPLES_PER_BUFFER,
   198       g_param_spec_int ("samplesperbuffer", "Samples per buffer",
   187       g_param_spec_int ("samplesperbuffer", "Samples per buffer",
   199           "Number of samples in each outgoing buffer",
   188           "Number of samples in each outgoing buffer",
   200           1, G_MAXINT, DEFAULT_SAMPLES_PER_BUFFER,
   189           1, G_MAXINT, 1024, G_PARAM_READWRITE));
   201           G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
   190   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 */
   202   g_object_class_install_property (gobject_class, PROP_WAVE,
   191           GST_AUDIO_TEST_SRC_WAVE_SINE, /* default value */
   203       g_param_spec_enum ("wave", "Waveform", "Oscillator waveform",
   192           G_PARAM_READWRITE | GST_PARAM_CONTROLLABLE));
   204           GST_TYPE_AUDIO_TEST_SRC_WAVE, GST_AUDIO_TEST_SRC_WAVE_SINE,
       
   205           G_PARAM_READWRITE | GST_PARAM_CONTROLLABLE | G_PARAM_STATIC_STRINGS));
       
   206   g_object_class_install_property (gobject_class, PROP_FREQ,
   193   g_object_class_install_property (gobject_class, PROP_FREQ,
   207       g_param_spec_double ("freq", "Frequency", "Frequency of test signal",
   194       g_param_spec_double ("freq", "Frequency", "Frequency of test signal",
   208           0.0, 20000.0, DEFAULT_FREQ,
   195           0.0, 20000.0, 440.0, G_PARAM_READWRITE | GST_PARAM_CONTROLLABLE));
   209           G_PARAM_READWRITE | GST_PARAM_CONTROLLABLE | G_PARAM_STATIC_STRINGS));
       
   210   g_object_class_install_property (gobject_class, PROP_VOLUME,
   196   g_object_class_install_property (gobject_class, PROP_VOLUME,
   211       g_param_spec_double ("volume", "Volume", "Volume of test signal", 0.0,
   197       g_param_spec_double ("volume", "Volume", "Volume of test signal",
   212           1.0, DEFAULT_VOLUME,
   198           0.0, 1.0, 0.8, G_PARAM_READWRITE | GST_PARAM_CONTROLLABLE));
   213           G_PARAM_READWRITE | GST_PARAM_CONTROLLABLE | G_PARAM_STATIC_STRINGS));
       
   214   g_object_class_install_property (gobject_class, PROP_IS_LIVE,
   199   g_object_class_install_property (gobject_class, PROP_IS_LIVE,
   215       g_param_spec_boolean ("is-live", "Is Live",
   200       g_param_spec_boolean ("is-live", "Is Live",
   216           "Whether to act as a live source", DEFAULT_IS_LIVE,
   201           "Whether to act as a live source", FALSE, G_PARAM_READWRITE));
   217           G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
       
   218   g_object_class_install_property (G_OBJECT_CLASS (klass),
   202   g_object_class_install_property (G_OBJECT_CLASS (klass),
   219       PROP_TIMESTAMP_OFFSET, g_param_spec_int64 ("timestamp-offset",
   203       PROP_TIMESTAMP_OFFSET,
   220           "Timestamp offset",
   204       g_param_spec_int64 ("timestamp-offset", "Timestamp offset",
   221           "An offset added to timestamps set on buffers (in ns)", G_MININT64,
   205           "An offset added to timestamps set on buffers (in ns)", G_MININT64,
   222           G_MAXINT64, DEFAULT_TIMESTAMP_OFFSET,
   206           G_MAXINT64, 0, G_PARAM_READWRITE));
   223           G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
       
   224   g_object_class_install_property (gobject_class, PROP_CAN_ACTIVATE_PUSH,
       
   225       g_param_spec_boolean ("can-activate-push", "Can activate push",
       
   226           "Can activate in push mode", DEFAULT_CAN_ACTIVATE_PUSH,
       
   227           G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
       
   228   g_object_class_install_property (gobject_class, PROP_CAN_ACTIVATE_PULL,
       
   229       g_param_spec_boolean ("can-activate-pull", "Can activate pull",
       
   230           "Can activate in pull mode", DEFAULT_CAN_ACTIVATE_PULL,
       
   231           G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
       
   232 
   207 
   233   gstbasesrc_class->set_caps = GST_DEBUG_FUNCPTR (gst_audio_test_src_setcaps);
   208   gstbasesrc_class->set_caps = GST_DEBUG_FUNCPTR (gst_audio_test_src_setcaps);
   234   gstbasesrc_class->is_seekable =
   209   gstbasesrc_class->is_seekable =
   235       GST_DEBUG_FUNCPTR (gst_audio_test_src_is_seekable);
   210       GST_DEBUG_FUNCPTR (gst_audio_test_src_is_seekable);
   236   gstbasesrc_class->check_get_range =
       
   237       GST_DEBUG_FUNCPTR (gst_audio_test_src_check_get_range);
       
   238   gstbasesrc_class->do_seek = GST_DEBUG_FUNCPTR (gst_audio_test_src_do_seek);
   211   gstbasesrc_class->do_seek = GST_DEBUG_FUNCPTR (gst_audio_test_src_do_seek);
   239   gstbasesrc_class->query = GST_DEBUG_FUNCPTR (gst_audio_test_src_query);
   212   gstbasesrc_class->query = GST_DEBUG_FUNCPTR (gst_audio_test_src_query);
   240   gstbasesrc_class->get_times =
   213   gstbasesrc_class->get_times =
   241       GST_DEBUG_FUNCPTR (gst_audio_test_src_get_times);
   214       GST_DEBUG_FUNCPTR (gst_audio_test_src_get_times);
   242   gstbasesrc_class->start = GST_DEBUG_FUNCPTR (gst_audio_test_src_start);
       
   243   gstbasesrc_class->stop = GST_DEBUG_FUNCPTR (gst_audio_test_src_stop);
       
   244   gstbasesrc_class->create = GST_DEBUG_FUNCPTR (gst_audio_test_src_create);
   215   gstbasesrc_class->create = GST_DEBUG_FUNCPTR (gst_audio_test_src_create);
   245 }
   216 }
   246 
   217 
   247 static void
   218 static void
   248 gst_audio_test_src_init (GstAudioTestSrc * src, GstAudioTestSrcClass * g_class)
   219 gst_audio_test_src_init (GstAudioTestSrc * src, GstAudioTestSrcClass * g_class)
   251 
   222 
   252   gst_pad_set_fixatecaps_function (pad, gst_audio_test_src_src_fixate);
   223   gst_pad_set_fixatecaps_function (pad, gst_audio_test_src_src_fixate);
   253 
   224 
   254   src->samplerate = 44100;
   225   src->samplerate = 44100;
   255   src->format = GST_AUDIO_TEST_SRC_FORMAT_NONE;
   226   src->format = GST_AUDIO_TEST_SRC_FORMAT_NONE;
   256 
   227   src->volume = 0.8;
   257   src->volume = DEFAULT_VOLUME;
   228   src->freq = 440.0;
   258   src->freq = DEFAULT_FREQ;
       
   259 
   229 
   260   /* we operate in time */
   230   /* we operate in time */
   261   gst_base_src_set_format (GST_BASE_SRC (src), GST_FORMAT_TIME);
   231   gst_base_src_set_format (GST_BASE_SRC (src), GST_FORMAT_TIME);
   262   gst_base_src_set_live (GST_BASE_SRC (src), DEFAULT_IS_LIVE);
   232   gst_base_src_set_live (GST_BASE_SRC (src), FALSE);
   263 
   233 
   264   src->samples_per_buffer = DEFAULT_SAMPLES_PER_BUFFER;
   234   src->samples_per_buffer = 1024;
   265   src->generate_samples_per_buffer = src->samples_per_buffer;
   235   src->generate_samples_per_buffer = src->samples_per_buffer;
   266   src->timestamp_offset = DEFAULT_TIMESTAMP_OFFSET;
   236   src->timestamp_offset = G_GINT64_CONSTANT (0);
   267   src->can_activate_pull = DEFAULT_CAN_ACTIVATE_PULL;
   237 
   268 
   238   src->wave = GST_AUDIO_TEST_SRC_WAVE_SINE;
   269   src->wave = DEFAULT_WAVE;
       
   270   gst_base_src_set_blocksize (GST_BASE_SRC (src), -1);
       
   271 }
   239 }
   272 
   240 
   273 static void
   241 static void
   274 gst_audio_test_src_src_fixate (GstPad * pad, GstCaps * caps)
   242 gst_audio_test_src_src_fixate (GstPad * pad, GstCaps * caps)
   275 {
   243 {
   276   GstAudioTestSrc *src = GST_AUDIO_TEST_SRC (GST_PAD_PARENT (pad));
   244   GstAudioTestSrc *src = GST_AUDIO_TEST_SRC (GST_PAD_PARENT (pad));
   277   const gchar *name;
   245   const gchar *name;
   278   GstStructure *structure;
   246   GstStructure *structure;
   279 
   247 
   280   structure = gst_caps_get_structure (caps, 0);
   248   structure = gst_caps_get_structure (caps, 0);
   281 
       
   282   GST_DEBUG_OBJECT (src, "fixating samplerate to %d", src->samplerate);
       
   283 
   249 
   284   gst_structure_fixate_field_nearest_int (structure, "rate", src->samplerate);
   250   gst_structure_fixate_field_nearest_int (structure, "rate", src->samplerate);
   285 
   251 
   286   name = gst_structure_get_name (structure);
   252   name = gst_structure_get_name (structure);
   287   if (strcmp (name, "audio/x-raw-int") == 0)
   253   if (strcmp (name, "audio/x-raw-int") == 0)
   288     gst_structure_fixate_field_nearest_int (structure, "width", 32);
   254     gst_structure_fixate_field_nearest_int (structure, "width", 32);
   289   else if (strcmp (name, "audio/x-raw-float") == 0)
   255   else if (strcmp (name, "audio/x-raw-float") == 0)
   290     gst_structure_fixate_field_nearest_int (structure, "width", 64);
   256     gst_structure_fixate_field_nearest_int (structure, "width", 64);
   291 
       
   292   /* fixate to mono unless downstream requires stereo, for backwards compat */
       
   293   gst_structure_fixate_field_nearest_int (structure, "channels", 1);
       
   294 }
   257 }
   295 
   258 
   296 static gboolean
   259 static gboolean
   297 gst_audio_test_src_setcaps (GstBaseSrc * basesrc, GstCaps * caps)
   260 gst_audio_test_src_setcaps (GstBaseSrc * basesrc, GstCaps * caps)
   298 {
   261 {
   302   gint width;
   265   gint width;
   303   gboolean ret;
   266   gboolean ret;
   304 
   267 
   305   structure = gst_caps_get_structure (caps, 0);
   268   structure = gst_caps_get_structure (caps, 0);
   306   ret = gst_structure_get_int (structure, "rate", &src->samplerate);
   269   ret = gst_structure_get_int (structure, "rate", &src->samplerate);
   307 
       
   308   GST_DEBUG_OBJECT (src, "negotiated to samplerate %d", src->samplerate);
       
   309 
   270 
   310   name = gst_structure_get_name (structure);
   271   name = gst_structure_get_name (structure);
   311   if (strcmp (name, "audio/x-raw-int") == 0) {
   272   if (strcmp (name, "audio/x-raw-int") == 0) {
   312     ret &= gst_structure_get_int (structure, "width", &width);
   273     ret &= gst_structure_get_int (structure, "width", &width);
   313     src->format = (width == 32) ? GST_AUDIO_TEST_SRC_FORMAT_S32 :
   274     src->format = (width == 32) ? GST_AUDIO_TEST_SRC_FORMAT_S32 :
   315   } else {
   276   } else {
   316     ret &= gst_structure_get_int (structure, "width", &width);
   277     ret &= gst_structure_get_int (structure, "width", &width);
   317     src->format = (width == 32) ? GST_AUDIO_TEST_SRC_FORMAT_F32 :
   278     src->format = (width == 32) ? GST_AUDIO_TEST_SRC_FORMAT_F32 :
   318         GST_AUDIO_TEST_SRC_FORMAT_F64;
   279         GST_AUDIO_TEST_SRC_FORMAT_F64;
   319   }
   280   }
   320 
       
   321   /* allocate a new buffer suitable for this pad */
       
   322   switch (src->format) {
       
   323     case GST_AUDIO_TEST_SRC_FORMAT_S16:
       
   324       src->sample_size = sizeof (gint16);
       
   325       break;
       
   326     case GST_AUDIO_TEST_SRC_FORMAT_S32:
       
   327       src->sample_size = sizeof (gint32);
       
   328       break;
       
   329     case GST_AUDIO_TEST_SRC_FORMAT_F32:
       
   330       src->sample_size = sizeof (gfloat);
       
   331       break;
       
   332     case GST_AUDIO_TEST_SRC_FORMAT_F64:
       
   333       src->sample_size = sizeof (gdouble);
       
   334       break;
       
   335     default:
       
   336       /* can't really happen */
       
   337       ret = FALSE;
       
   338       break;
       
   339   }
       
   340 
       
   341   ret &= gst_structure_get_int (structure, "channels", &src->channels);
       
   342   GST_DEBUG_OBJECT (src, "negotiated to %d channels", src->channels);
       
   343 
   281 
   344   gst_audio_test_src_change_wave (src);
   282   gst_audio_test_src_change_wave (src);
   345 
   283 
   346   return ret;
   284   return ret;
   347 }
   285 }
   413 
   351 
   414 #define DEFINE_SINE(type,scale) \
   352 #define DEFINE_SINE(type,scale) \
   415 static void \
   353 static void \
   416 gst_audio_test_src_create_sine_##type (GstAudioTestSrc * src, g##type * samples) \
   354 gst_audio_test_src_create_sine_##type (GstAudioTestSrc * src, g##type * samples) \
   417 { \
   355 { \
   418   gint i, c; \
   356   gint i; \
   419   gdouble step, amp; \
   357   gdouble step, amp; \
   420   \
   358   \
   421   step = M_PI_M2 * src->freq / src->samplerate; \
   359   step = M_PI_M2 * src->freq / src->samplerate; \
   422   amp = src->volume * scale; \
   360   amp = src->volume * scale; \
   423   \
   361   \
   424   i = 0; \
   362   for (i = 0; i < src->generate_samples_per_buffer; i++) { \
   425   while (i < (src->generate_samples_per_buffer * src->channels)) { \
       
   426     src->accumulator += step; \
   363     src->accumulator += step; \
   427     if (src->accumulator >= M_PI_M2) \
   364     if (src->accumulator >= M_PI_M2) \
   428       src->accumulator -= M_PI_M2; \
   365       src->accumulator -= M_PI_M2; \
   429     \
   366     \
   430     for (c = 0; c < src->channels; ++c) { \
   367     samples[i] = (g##type) (sin (src->accumulator) * amp); \
   431       samples[i++] = (g##type) (sin (src->accumulator) * amp); \
       
   432     } \
       
   433   } \
   368   } \
   434 }
   369 }
   435 
   370 
   436 DEFINE_SINE (int16, 32767.0);
   371 DEFINE_SINE (int16, 32767.0);
   437 DEFINE_SINE (int32, 2147483647.0);
   372 DEFINE_SINE (int32, 2147483647.0);
   438 DEFINE_SINE (float, 1.0);
   373 DEFINE_SINE (float, 1.0);
   439 DEFINE_SINE (double, 1.0);
   374 DEFINE_SINE (double, 1.0);
   440 
   375 
   441 static const ProcessFunc sine_funcs[] = {
   376 static ProcessFunc sine_funcs[] = {
   442   (ProcessFunc) gst_audio_test_src_create_sine_int16,
   377   (ProcessFunc) gst_audio_test_src_create_sine_int16,
   443   (ProcessFunc) gst_audio_test_src_create_sine_int32,
   378   (ProcessFunc) gst_audio_test_src_create_sine_int32,
   444   (ProcessFunc) gst_audio_test_src_create_sine_float,
   379   (ProcessFunc) gst_audio_test_src_create_sine_float,
   445   (ProcessFunc) gst_audio_test_src_create_sine_double
   380   (ProcessFunc) gst_audio_test_src_create_sine_double
   446 };
   381 };
   447 
   382 
   448 #define DEFINE_SQUARE(type,scale) \
   383 #define DEFINE_SQUARE(type,scale) \
   449 static void \
   384 static void \
   450 gst_audio_test_src_create_square_##type (GstAudioTestSrc * src, g##type * samples) \
   385 gst_audio_test_src_create_square_##type (GstAudioTestSrc * src, g##type * samples) \
   451 { \
   386 { \
   452   gint i, c; \
   387   gint i; \
   453   gdouble step, amp; \
   388   gdouble step, amp; \
   454   \
   389   \
   455   step = M_PI_M2 * src->freq / src->samplerate; \
   390   step = M_PI_M2 * src->freq / src->samplerate; \
   456   amp = src->volume * scale; \
   391   amp = src->volume * scale; \
   457   \
   392   \
   458   i = 0; \
   393   for (i = 0; i < src->generate_samples_per_buffer; i++) { \
   459   while (i < (src->generate_samples_per_buffer * src->channels)) { \
       
   460     src->accumulator += step; \
   394     src->accumulator += step; \
   461     if (src->accumulator >= M_PI_M2) \
   395     if (src->accumulator >= M_PI_M2) \
   462       src->accumulator -= M_PI_M2; \
   396       src->accumulator -= M_PI_M2; \
   463     \
   397     \
   464     for (c = 0; c < src->channels; ++c) { \
   398     samples[i] = (g##type) ((src->accumulator < M_PI) ? amp : -amp); \
   465       samples[i++] = (g##type) ((src->accumulator < M_PI) ? amp : -amp); \
       
   466     } \
       
   467   } \
   399   } \
   468 }
   400 }
   469 
   401 
   470 DEFINE_SQUARE (int16, 32767.0);
   402 DEFINE_SQUARE (int16, 32767.0);
   471 DEFINE_SQUARE (int32, 2147483647.0);
   403 DEFINE_SQUARE (int32, 2147483647.0);
   472 DEFINE_SQUARE (float, 1.0);
   404 DEFINE_SQUARE (float, 1.0);
   473 DEFINE_SQUARE (double, 1.0);
   405 DEFINE_SQUARE (double, 1.0);
   474 
   406 
   475 static const ProcessFunc square_funcs[] = {
   407 static ProcessFunc square_funcs[] = {
   476   (ProcessFunc) gst_audio_test_src_create_square_int16,
   408   (ProcessFunc) gst_audio_test_src_create_square_int16,
   477   (ProcessFunc) gst_audio_test_src_create_square_int32,
   409   (ProcessFunc) gst_audio_test_src_create_square_int32,
   478   (ProcessFunc) gst_audio_test_src_create_square_float,
   410   (ProcessFunc) gst_audio_test_src_create_square_float,
   479   (ProcessFunc) gst_audio_test_src_create_square_double
   411   (ProcessFunc) gst_audio_test_src_create_square_double
   480 };
   412 };
   481 
   413 
   482 #define DEFINE_SAW(type,scale) \
   414 #define DEFINE_SAW(type,scale) \
   483 static void \
   415 static void \
   484 gst_audio_test_src_create_saw_##type (GstAudioTestSrc * src, g##type * samples) \
   416 gst_audio_test_src_create_saw_##type (GstAudioTestSrc * src, g##type * samples) \
   485 { \
   417 { \
   486   gint i, c; \
   418   gint i; \
   487   gdouble step, amp; \
   419   gdouble step, amp; \
   488   \
   420   \
   489   step = M_PI_M2 * src->freq / src->samplerate; \
   421   step = M_PI_M2 * src->freq / src->samplerate; \
   490   amp = (src->volume * scale) / M_PI; \
   422   amp = (src->volume * scale) / M_PI; \
   491   \
   423   \
   492   i = 0; \
   424   for (i = 0; i < src->generate_samples_per_buffer; i++) { \
   493   while (i < (src->generate_samples_per_buffer * src->channels)) { \
       
   494     src->accumulator += step; \
   425     src->accumulator += step; \
   495     if (src->accumulator >= M_PI_M2) \
   426     if (src->accumulator >= M_PI_M2) \
   496       src->accumulator -= M_PI_M2; \
   427       src->accumulator -= M_PI_M2; \
   497     \
   428     \
   498     if (src->accumulator < M_PI) { \
   429     if (src->accumulator < M_PI) { \
   499       for (c = 0; c < src->channels; ++c) \
   430       samples[i] = (g##type) (src->accumulator * amp); \
   500         samples[i++] = (g##type) (src->accumulator * amp); \
       
   501     } else { \
   431     } else { \
   502       for (c = 0; c < src->channels; ++c) \
   432       samples[i] = (g##type) ((M_PI_M2 - src->accumulator) * -amp); \
   503         samples[i++] = (g##type) ((M_PI_M2 - src->accumulator) * -amp); \
       
   504     } \
   433     } \
   505   } \
   434   } \
   506 }
   435 }
   507 
   436 
   508 DEFINE_SAW (int16, 32767.0);
   437 DEFINE_SAW (int16, 32767.0);
   509 DEFINE_SAW (int32, 2147483647.0);
   438 DEFINE_SAW (int32, 2147483647.0);
   510 DEFINE_SAW (float, 1.0);
   439 DEFINE_SAW (float, 1.0);
   511 DEFINE_SAW (double, 1.0);
   440 DEFINE_SAW (double, 1.0);
   512 
   441 
   513 static const ProcessFunc saw_funcs[] = {
   442 static ProcessFunc saw_funcs[] = {
   514   (ProcessFunc) gst_audio_test_src_create_saw_int16,
   443   (ProcessFunc) gst_audio_test_src_create_saw_int16,
   515   (ProcessFunc) gst_audio_test_src_create_saw_int32,
   444   (ProcessFunc) gst_audio_test_src_create_saw_int32,
   516   (ProcessFunc) gst_audio_test_src_create_saw_float,
   445   (ProcessFunc) gst_audio_test_src_create_saw_float,
   517   (ProcessFunc) gst_audio_test_src_create_saw_double
   446   (ProcessFunc) gst_audio_test_src_create_saw_double
   518 };
   447 };
   519 
   448 
   520 #define DEFINE_TRIANGLE(type,scale) \
   449 #define DEFINE_TRIANGLE(type,scale) \
   521 static void \
   450 static void \
   522 gst_audio_test_src_create_triangle_##type (GstAudioTestSrc * src, g##type * samples) \
   451 gst_audio_test_src_create_triangle_##type (GstAudioTestSrc * src, g##type * samples) \
   523 { \
   452 { \
   524   gint i, c; \
   453   gint i; \
   525   gdouble step, amp; \
   454   gdouble step, amp; \
   526   \
   455   \
   527   step = M_PI_M2 * src->freq / src->samplerate; \
   456   step = M_PI_M2 * src->freq / src->samplerate; \
   528   amp = (src->volume * scale) / M_PI_2; \
   457   amp = (src->volume * scale) / M_PI_2; \
   529   \
   458   \
   530   i = 0; \
   459   for (i = 0; i < src->generate_samples_per_buffer; i++) { \
   531   while (i < (src->generate_samples_per_buffer * src->channels)) { \
       
   532     src->accumulator += step; \
   460     src->accumulator += step; \
   533     if (src->accumulator >= M_PI_M2) \
   461     if (src->accumulator >= M_PI_M2) \
   534       src->accumulator -= M_PI_M2; \
   462       src->accumulator -= M_PI_M2; \
   535     \
   463     \
   536     if (src->accumulator < (M_PI * 0.5)) { \
   464     if (src->accumulator < (M_PI * 0.5)) { \
   537       for (c = 0; c < src->channels; ++c) \
   465       samples[i] = (g##type) (src->accumulator * amp); \
   538         samples[i++] = (g##type) (src->accumulator * amp); \
       
   539     } else if (src->accumulator < (M_PI * 1.5)) { \
   466     } else if (src->accumulator < (M_PI * 1.5)) { \
   540       for (c = 0; c < src->channels; ++c) \
   467       samples[i] = (g##type) ((src->accumulator - M_PI) * -amp); \
   541         samples[i++] = (g##type) ((src->accumulator - M_PI) * -amp); \
       
   542     } else { \
   468     } else { \
   543       for (c = 0; c < src->channels; ++c) \
   469       samples[i] = (g##type) ((M_PI_M2 - src->accumulator) * -amp); \
   544         samples[i++] = (g##type) ((M_PI_M2 - src->accumulator) * -amp); \
       
   545     } \
   470     } \
   546   } \
   471   } \
   547 }
   472 }
   548 
   473 
   549 DEFINE_TRIANGLE (int16, 32767.0);
   474 DEFINE_TRIANGLE (int16, 32767.0);
   550 DEFINE_TRIANGLE (int32, 2147483647.0);
   475 DEFINE_TRIANGLE (int32, 2147483647.0);
   551 DEFINE_TRIANGLE (float, 1.0);
   476 DEFINE_TRIANGLE (float, 1.0);
   552 DEFINE_TRIANGLE (double, 1.0);
   477 DEFINE_TRIANGLE (double, 1.0);
   553 
   478 
   554 static const ProcessFunc triangle_funcs[] = {
   479 static ProcessFunc triangle_funcs[] = {
   555   (ProcessFunc) gst_audio_test_src_create_triangle_int16,
   480   (ProcessFunc) gst_audio_test_src_create_triangle_int16,
   556   (ProcessFunc) gst_audio_test_src_create_triangle_int32,
   481   (ProcessFunc) gst_audio_test_src_create_triangle_int32,
   557   (ProcessFunc) gst_audio_test_src_create_triangle_float,
   482   (ProcessFunc) gst_audio_test_src_create_triangle_float,
   558   (ProcessFunc) gst_audio_test_src_create_triangle_double
   483   (ProcessFunc) gst_audio_test_src_create_triangle_double
   559 };
   484 };
   560 
   485 
   561 #define DEFINE_SILENCE(type) \
   486 #define DEFINE_SILENCE(type) \
   562 static void \
   487 static void \
   563 gst_audio_test_src_create_silence_##type (GstAudioTestSrc * src, g##type * samples) \
   488 gst_audio_test_src_create_silence_##type (GstAudioTestSrc * src, g##type * samples) \
   564 { \
   489 { \
   565   memset (samples, 0, src->generate_samples_per_buffer * sizeof (g##type) * src->channels); \
   490   memset (samples, 0, src->generate_samples_per_buffer * sizeof (g##type)); \
   566 }
   491 }
   567 
   492 
   568 DEFINE_SILENCE (int16);
   493 DEFINE_SILENCE (int16);
   569 DEFINE_SILENCE (int32);
   494 DEFINE_SILENCE (int32);
   570 DEFINE_SILENCE (float);
   495 DEFINE_SILENCE (float);
   571 DEFINE_SILENCE (double);
   496 DEFINE_SILENCE (double);
   572 
   497 
   573 static const ProcessFunc silence_funcs[] = {
   498 static ProcessFunc silence_funcs[] = {
   574   (ProcessFunc) gst_audio_test_src_create_silence_int16,
   499   (ProcessFunc) gst_audio_test_src_create_silence_int16,
   575   (ProcessFunc) gst_audio_test_src_create_silence_int32,
   500   (ProcessFunc) gst_audio_test_src_create_silence_int32,
   576   (ProcessFunc) gst_audio_test_src_create_silence_float,
   501   (ProcessFunc) gst_audio_test_src_create_silence_float,
   577   (ProcessFunc) gst_audio_test_src_create_silence_double
   502   (ProcessFunc) gst_audio_test_src_create_silence_double
   578 };
   503 };
   579 
   504 
   580 #define DEFINE_WHITE_NOISE(type,scale) \
   505 #define DEFINE_WHITE_NOISE(type,scale) \
   581 static void \
   506 static void \
   582 gst_audio_test_src_create_white_noise_##type (GstAudioTestSrc * src, g##type * samples) \
   507 gst_audio_test_src_create_white_noise_##type (GstAudioTestSrc * src, g##type * samples) \
   583 { \
   508 { \
   584   gint i, c; \
   509   gint i; \
   585   gdouble amp = (src->volume * scale); \
   510   gdouble amp = (src->volume * scale); \
   586   \
   511   \
   587   i = 0; \
   512   for (i = 0; i < src->generate_samples_per_buffer; i++) { \
   588   while (i < (src->generate_samples_per_buffer * src->channels)) { \
   513     samples[i] = (g##type) (amp * g_random_double_range (-1.0, 1.0)); \
   589     for (c = 0; c < src->channels; ++c) \
       
   590       samples[i++] = (g##type) (amp * g_random_double_range (-1.0, 1.0)); \
       
   591   } \
   514   } \
   592 }
   515 }
   593 
   516 
   594 DEFINE_WHITE_NOISE (int16, 32767.0);
   517 DEFINE_WHITE_NOISE (int16, 32767.0);
   595 DEFINE_WHITE_NOISE (int32, 2147483647.0);
   518 DEFINE_WHITE_NOISE (int32, 2147483647.0);
   596 DEFINE_WHITE_NOISE (float, 1.0);
   519 DEFINE_WHITE_NOISE (float, 1.0);
   597 DEFINE_WHITE_NOISE (double, 1.0);
   520 DEFINE_WHITE_NOISE (double, 1.0);
   598 
   521 
   599 static const ProcessFunc white_noise_funcs[] = {
   522 static ProcessFunc white_noise_funcs[] = {
   600   (ProcessFunc) gst_audio_test_src_create_white_noise_int16,
   523   (ProcessFunc) gst_audio_test_src_create_white_noise_int16,
   601   (ProcessFunc) gst_audio_test_src_create_white_noise_int32,
   524   (ProcessFunc) gst_audio_test_src_create_white_noise_int32,
   602   (ProcessFunc) gst_audio_test_src_create_white_noise_float,
   525   (ProcessFunc) gst_audio_test_src_create_white_noise_float,
   603   (ProcessFunc) gst_audio_test_src_create_white_noise_double
   526   (ProcessFunc) gst_audio_test_src_create_white_noise_double
   604 };
   527 };
   652     /* Replace the indexed ROWS random value.
   575     /* Replace the indexed ROWS random value.
   653      * Subtract and add back to RunningSum instead of adding all the random
   576      * Subtract and add back to RunningSum instead of adding all the random
   654      * values together. Only one changes each time.
   577      * values together. Only one changes each time.
   655      */
   578      */
   656     pink->running_sum -= pink->rows[num_zeros];
   579     pink->running_sum -= pink->rows[num_zeros];
       
   580     //new_random = ((glong)GenerateRandomNumber()) >> PINK_RANDOM_SHIFT;
   657     new_random = 32768.0 - (65536.0 * (gulong) rand () / (RAND_MAX + 1.0));
   581     new_random = 32768.0 - (65536.0 * (gulong) rand () / (RAND_MAX + 1.0));
   658     pink->running_sum += new_random;
   582     pink->running_sum += new_random;
   659     pink->rows[num_zeros] = new_random;
   583     pink->rows[num_zeros] = new_random;
   660   }
   584   }
   661 
   585 
   669 
   593 
   670 #define DEFINE_PINK(type, scale) \
   594 #define DEFINE_PINK(type, scale) \
   671 static void \
   595 static void \
   672 gst_audio_test_src_create_pink_noise_##type (GstAudioTestSrc * src, g##type * samples) \
   596 gst_audio_test_src_create_pink_noise_##type (GstAudioTestSrc * src, g##type * samples) \
   673 { \
   597 { \
   674   gint i, c; \
   598   gint i; \
   675   gdouble amp; \
   599   gdouble amp; \
   676   \
   600   \
   677   amp = src->volume * scale; \
   601   amp = src->volume * scale; \
   678   \
   602   \
   679   i = 0; \
   603   for (i = 0; i < src->generate_samples_per_buffer; i++) { \
   680   while (i < (src->generate_samples_per_buffer * src->channels)) { \
   604     samples[i] = \
   681     for (c = 0; c < src->channels; ++c) { \
       
   682       samples[i++] = \
       
   683         (g##type) (gst_audio_test_src_generate_pink_noise_value (&src->pink) * \
   605         (g##type) (gst_audio_test_src_generate_pink_noise_value (&src->pink) * \
   684         amp); \
   606         amp); \
   685     } \
       
   686   } \
   607   } \
   687 }
   608 }
   688 
   609 
   689 DEFINE_PINK (int16, 32767.0);
   610 DEFINE_PINK (int16, 32767.0);
   690 DEFINE_PINK (int32, 2147483647.0);
   611 DEFINE_PINK (int32, 2147483647.0);
   691 DEFINE_PINK (float, 1.0);
   612 DEFINE_PINK (float, 1.0);
   692 DEFINE_PINK (double, 1.0);
   613 DEFINE_PINK (double, 1.0);
   693 
   614 
   694 static const ProcessFunc pink_noise_funcs[] = {
   615 static ProcessFunc pink_noise_funcs[] = {
   695   (ProcessFunc) gst_audio_test_src_create_pink_noise_int16,
   616   (ProcessFunc) gst_audio_test_src_create_pink_noise_int16,
   696   (ProcessFunc) gst_audio_test_src_create_pink_noise_int32,
   617   (ProcessFunc) gst_audio_test_src_create_pink_noise_int32,
   697   (ProcessFunc) gst_audio_test_src_create_pink_noise_float,
   618   (ProcessFunc) gst_audio_test_src_create_pink_noise_float,
   698   (ProcessFunc) gst_audio_test_src_create_pink_noise_double
   619   (ProcessFunc) gst_audio_test_src_create_pink_noise_double
   699 };
   620 };
   714 
   635 
   715 #define DEFINE_SINE_TABLE(type,scale) \
   636 #define DEFINE_SINE_TABLE(type,scale) \
   716 static void \
   637 static void \
   717 gst_audio_test_src_create_sine_table_##type (GstAudioTestSrc * src, g##type * samples) \
   638 gst_audio_test_src_create_sine_table_##type (GstAudioTestSrc * src, g##type * samples) \
   718 { \
   639 { \
   719   gint i, c; \
   640   gint i; \
   720   gdouble step, scl; \
   641   gdouble step, scl; \
   721   \
   642   \
   722   step = M_PI_M2 * src->freq / src->samplerate; \
   643   step = M_PI_M2 * src->freq / src->samplerate; \
   723   scl = 1024.0 / M_PI_M2; \
   644   scl = 1024.0 / M_PI_M2; \
   724   \
   645   \
   725   i = 0; \
   646   for (i = 0; i < src->generate_samples_per_buffer; i++) { \
   726   while (i < (src->generate_samples_per_buffer * src->channels)) { \
       
   727     src->accumulator += step; \
   647     src->accumulator += step; \
   728     if (src->accumulator >= M_PI_M2) \
   648     if (src->accumulator >= M_PI_M2) \
   729       src->accumulator -= M_PI_M2; \
   649       src->accumulator -= M_PI_M2; \
   730     \
   650     \
   731     for (c = 0; c < src->channels; ++c) \
   651     samples[i] = (g##type) scale * src->wave_table[(gint) (src->accumulator * scl)]; \
   732       samples[i++] = (g##type) scale * src->wave_table[(gint) (src->accumulator * scl)]; \
       
   733   } \
   652   } \
   734 }
   653 }
   735 
   654 
   736 DEFINE_SINE_TABLE (int16, 32767.0);
   655 DEFINE_SINE_TABLE (int16, 32767.0);
   737 DEFINE_SINE_TABLE (int32, 2147483647.0);
   656 DEFINE_SINE_TABLE (int32, 2147483647.0);
   738 DEFINE_SINE_TABLE (float, 1.0);
   657 DEFINE_SINE_TABLE (float, 1.0);
   739 DEFINE_SINE_TABLE (double, 1.0);
   658 DEFINE_SINE_TABLE (double, 1.0);
   740 
   659 
   741 static const ProcessFunc sine_table_funcs[] = {
   660 static ProcessFunc sine_table_funcs[] = {
   742   (ProcessFunc) gst_audio_test_src_create_sine_table_int16,
   661   (ProcessFunc) gst_audio_test_src_create_sine_table_int16,
   743   (ProcessFunc) gst_audio_test_src_create_sine_table_int32,
   662   (ProcessFunc) gst_audio_test_src_create_sine_table_int32,
   744   (ProcessFunc) gst_audio_test_src_create_sine_table_float,
   663   (ProcessFunc) gst_audio_test_src_create_sine_table_float,
   745   (ProcessFunc) gst_audio_test_src_create_sine_table_double
   664   (ProcessFunc) gst_audio_test_src_create_sine_table_double
   746 };
   665 };
   747 
   666 
   748 #define DEFINE_TICKS(type,scale) \
       
   749 static void \
       
   750 gst_audio_test_src_create_tick_##type (GstAudioTestSrc * src, g##type * samples) \
       
   751 { \
       
   752   gint i, c; \
       
   753   gdouble step, scl; \
       
   754   \
       
   755   step = M_PI_M2 * src->freq / src->samplerate; \
       
   756   scl = 1024.0 / M_PI_M2; \
       
   757   \
       
   758   for (i = 0; i < src->generate_samples_per_buffer; i++) { \
       
   759     src->accumulator += step; \
       
   760     if (src->accumulator >= M_PI_M2) \
       
   761       src->accumulator -= M_PI_M2; \
       
   762     \
       
   763     if ((src->next_sample + i)%src->samplerate < 1600) { \
       
   764       for (c = 0; c < src->channels; ++c) \
       
   765         samples[(i * src->channels) + c] = (g##type) scale * src->wave_table[(gint) (src->accumulator * scl)]; \
       
   766     } else { \
       
   767       for (c = 0; c < src->channels; ++c) \
       
   768         samples[(i * src->channels) + c] = 0; \
       
   769     } \
       
   770   } \
       
   771 }
       
   772 
       
   773 DEFINE_TICKS (int16, 32767.0);
       
   774 DEFINE_TICKS (int32, 2147483647.0);
       
   775 DEFINE_TICKS (float, 1.0);
       
   776 DEFINE_TICKS (double, 1.0);
       
   777 
       
   778 static const ProcessFunc tick_funcs[] = {
       
   779   (ProcessFunc) gst_audio_test_src_create_tick_int16,
       
   780   (ProcessFunc) gst_audio_test_src_create_tick_int32,
       
   781   (ProcessFunc) gst_audio_test_src_create_tick_float,
       
   782   (ProcessFunc) gst_audio_test_src_create_tick_double
       
   783 };
       
   784 
       
   785 /* Gaussian white noise using Box-Muller algorithm.  unit variance
       
   786  * normally-distributed random numbers are generated in pairs as the real
       
   787  * and imaginary parts of a compex random variable with
       
   788  * uniformly-distributed argument and \chi^{2}-distributed modulus.
       
   789  */
       
   790 
       
   791 #define DEFINE_GAUSSIAN_WHITE_NOISE(type,scale) \
       
   792 static void \
       
   793 gst_audio_test_src_create_gaussian_white_noise_##type (GstAudioTestSrc * src, g##type * samples) \
       
   794 { \
       
   795   gint i, c; \
       
   796   gdouble amp = (src->volume * scale); \
       
   797   \
       
   798   for (i = 0; i < src->generate_samples_per_buffer * src->channels; ) { \
       
   799     for (c = 0; c < src->channels; ++c) { \
       
   800       gdouble mag = sqrt (-2 * log (1.0 - g_random_double ())); \
       
   801       gdouble phs = g_random_double_range (0.0, M_PI_M2); \
       
   802       \
       
   803       samples[i++] = (g##type) (amp * mag * cos (phs)); \
       
   804       if (++c >= src->channels) \
       
   805         break; \
       
   806       samples[i++] = (g##type) (amp * mag * sin (phs)); \
       
   807     } \
       
   808   } \
       
   809 }
       
   810 
       
   811 DEFINE_GAUSSIAN_WHITE_NOISE (int16, 32767.0);
       
   812 DEFINE_GAUSSIAN_WHITE_NOISE (int32, 2147483647.0);
       
   813 DEFINE_GAUSSIAN_WHITE_NOISE (float, 1.0);
       
   814 DEFINE_GAUSSIAN_WHITE_NOISE (double, 1.0);
       
   815 
       
   816 static const ProcessFunc gaussian_white_noise_funcs[] = {
       
   817   (ProcessFunc) gst_audio_test_src_create_gaussian_white_noise_int16,
       
   818   (ProcessFunc) gst_audio_test_src_create_gaussian_white_noise_int32,
       
   819   (ProcessFunc) gst_audio_test_src_create_gaussian_white_noise_float,
       
   820   (ProcessFunc) gst_audio_test_src_create_gaussian_white_noise_double
       
   821 };
       
   822 
       
   823 /*
   667 /*
   824  * gst_audio_test_src_change_wave:
   668  * gst_audio_test_src_change_wave:
   825  * Assign function pointer of wave genrator.
   669  * Assign function pointer of wave genrator.
   826  */
   670  */
   827 static void
   671 static void
   856       src->process = pink_noise_funcs[src->format];
   700       src->process = pink_noise_funcs[src->format];
   857       break;
   701       break;
   858     case GST_AUDIO_TEST_SRC_WAVE_SINE_TAB:
   702     case GST_AUDIO_TEST_SRC_WAVE_SINE_TAB:
   859       gst_audio_test_src_init_sine_table (src);
   703       gst_audio_test_src_init_sine_table (src);
   860       src->process = sine_table_funcs[src->format];
   704       src->process = sine_table_funcs[src->format];
   861       break;
       
   862     case GST_AUDIO_TEST_SRC_WAVE_TICKS:
       
   863       gst_audio_test_src_init_sine_table (src);
       
   864       src->process = tick_funcs[src->format];
       
   865       break;
       
   866     case GST_AUDIO_TEST_SRC_WAVE_GAUSSIAN_WHITE_NOISE:
       
   867       src->process = gaussian_white_noise_funcs[src->format];
       
   868       break;
   705       break;
   869     default:
   706     default:
   870       GST_ERROR ("invalid wave-form");
   707       GST_ERROR ("invalid wave-form");
   871       break;
   708       break;
   872   }
   709   }
   910     *end = -1;
   747     *end = -1;
   911   }
   748   }
   912 }
   749 }
   913 
   750 
   914 static gboolean
   751 static gboolean
   915 gst_audio_test_src_start (GstBaseSrc * basesrc)
       
   916 {
       
   917   GstAudioTestSrc *src = GST_AUDIO_TEST_SRC (basesrc);
       
   918 
       
   919   src->next_sample = 0;
       
   920   src->next_byte = 0;
       
   921   src->next_time = 0;
       
   922   src->check_seek_stop = FALSE;
       
   923   src->eos_reached = FALSE;
       
   924   src->tags_pushed = FALSE;
       
   925   src->accumulator = 0;
       
   926 
       
   927   return TRUE;
       
   928 }
       
   929 
       
   930 static gboolean
       
   931 gst_audio_test_src_stop (GstBaseSrc * basesrc)
       
   932 {
       
   933   return TRUE;
       
   934 }
       
   935 
       
   936 /* seek to time, will be called when we operate in push mode. In pull mode we
       
   937  * get the requested byte offset. */
       
   938 static gboolean
       
   939 gst_audio_test_src_do_seek (GstBaseSrc * basesrc, GstSegment * segment)
   752 gst_audio_test_src_do_seek (GstBaseSrc * basesrc, GstSegment * segment)
   940 {
   753 {
   941   GstAudioTestSrc *src = GST_AUDIO_TEST_SRC (basesrc);
   754   GstAudioTestSrc *src = GST_AUDIO_TEST_SRC (basesrc);
   942   GstClockTime time;
   755   GstClockTime time;
   943 
   756 
   944   segment->time = segment->start;
   757   segment->time = segment->start;
   945   time = segment->last_stop;
   758   time = segment->last_stop;
   946 
   759 
   947   /* now move to the time indicated */
   760   /* now move to the time indicated */
   948   src->next_sample =
   761   src->n_samples =
   949       gst_util_uint64_scale_int (time, src->samplerate, GST_SECOND);
   762       gst_util_uint64_scale_int (time, src->samplerate, GST_SECOND);
   950   src->next_byte = src->next_sample * src->sample_size * src->channels;
   763   src->running_time =
   951   src->next_time =
   764       gst_util_uint64_scale_int (src->n_samples, GST_SECOND, src->samplerate);
   952       gst_util_uint64_scale_int (src->next_sample, GST_SECOND, src->samplerate);
   765 
   953 
   766   g_assert (src->running_time <= time);
   954   g_assert (src->next_time <= time);
       
   955 
   767 
   956   if (GST_CLOCK_TIME_IS_VALID (segment->stop)) {
   768   if (GST_CLOCK_TIME_IS_VALID (segment->stop)) {
   957     time = segment->stop;
   769     time = segment->stop;
   958     src->sample_stop = gst_util_uint64_scale_int (time, src->samplerate,
   770     src->n_samples_stop = gst_util_uint64_scale_int (time, src->samplerate,
   959         GST_SECOND);
   771         GST_SECOND);
   960     src->check_seek_stop = TRUE;
   772     src->check_seek_stop = TRUE;
   961   } else {
   773   } else {
   962     src->check_seek_stop = FALSE;
   774     src->check_seek_stop = FALSE;
   963   }
   775   }
   971 {
   783 {
   972   /* we're seekable... */
   784   /* we're seekable... */
   973   return TRUE;
   785   return TRUE;
   974 }
   786 }
   975 
   787 
   976 static gboolean
       
   977 gst_audio_test_src_check_get_range (GstBaseSrc * basesrc)
       
   978 {
       
   979   GstAudioTestSrc *src;
       
   980 
       
   981   src = GST_AUDIO_TEST_SRC (basesrc);
       
   982 
       
   983   /* if we can operate in pull mode */
       
   984   return src->can_activate_pull;
       
   985 }
       
   986 
       
   987 static GstFlowReturn
   788 static GstFlowReturn
   988 gst_audio_test_src_create (GstBaseSrc * basesrc, guint64 offset,
   789 gst_audio_test_src_create (GstBaseSrc * basesrc, guint64 offset,
   989     guint length, GstBuffer ** buffer)
   790     guint length, GstBuffer ** buffer)
   990 {
   791 {
   991   GstFlowReturn res;
   792   GstFlowReturn res;
   992   GstAudioTestSrc *src;
   793   GstAudioTestSrc *src;
   993   GstBuffer *buf;
   794   GstBuffer *buf;
   994   GstClockTime next_time;
   795   GstClockTime next_time;
   995   gint64 next_sample, next_byte;
   796   gint64 n_samples;
   996   guint bytes, samples;
   797   gint sample_size;
   997   GstElementClass *eclass;
       
   998 
   798 
   999   src = GST_AUDIO_TEST_SRC (basesrc);
   799   src = GST_AUDIO_TEST_SRC (basesrc);
       
   800 
       
   801   if (src->eos_reached)
       
   802     return GST_FLOW_UNEXPECTED;
  1000 
   803 
  1001   /* example for tagging generated data */
   804   /* example for tagging generated data */
  1002   if (!src->tags_pushed) {
   805   if (!src->tags_pushed) {
  1003     GstTagList *taglist;
   806     GstTagList *taglist;
       
   807     GstEvent *event;
  1004 
   808 
  1005     taglist = gst_tag_list_new ();
   809     taglist = gst_tag_list_new ();
  1006 
   810 
  1007     gst_tag_list_add (taglist, GST_TAG_MERGE_APPEND,
   811     gst_tag_list_add (taglist, GST_TAG_MERGE_APPEND,
  1008         GST_TAG_DESCRIPTION, "audiotest wave", NULL);
   812         GST_TAG_DESCRIPTION, "audiotest wave", NULL);
  1009 
   813 
  1010     eclass = GST_ELEMENT_CLASS (parent_class);
   814     event = gst_event_new_tag (taglist);
  1011     if (eclass->send_event)
   815     gst_pad_push_event (basesrc->srcpad, event);
  1012       eclass->send_event (GST_ELEMENT_CAST (basesrc),
       
  1013           gst_event_new_tag (taglist));
       
  1014     src->tags_pushed = TRUE;
   816     src->tags_pushed = TRUE;
  1015   }
       
  1016 
       
  1017   if (src->eos_reached)
       
  1018     return GST_FLOW_UNEXPECTED;
       
  1019 
       
  1020   /* if no length was given, use our default length in samples otherwise convert
       
  1021    * the length in bytes to samples. */
       
  1022   if (length == -1)
       
  1023     samples = src->samples_per_buffer;
       
  1024   else
       
  1025     samples = length / (src->sample_size * src->channels);
       
  1026 
       
  1027   /* if no offset was given, use our next logical byte */
       
  1028   if (offset == -1)
       
  1029     offset = src->next_byte;
       
  1030 
       
  1031   /* now see if we are at the byteoffset we think we are */
       
  1032   if (offset != src->next_byte) {
       
  1033     GST_DEBUG_OBJECT (src, "seek to new offset %" G_GUINT64_FORMAT, offset);
       
  1034     /* we have a discont in the expected sample offset, do a 'seek' */
       
  1035     src->next_sample = offset / (src->sample_size * src->channels);
       
  1036     src->next_time =
       
  1037         gst_util_uint64_scale_int (src->next_sample, GST_SECOND,
       
  1038         src->samplerate);
       
  1039     src->next_byte = offset;
       
  1040   }
   817   }
  1041 
   818 
  1042   /* check for eos */
   819   /* check for eos */
  1043   if (src->check_seek_stop &&
   820   if (src->check_seek_stop &&
  1044       (src->sample_stop > src->next_sample) &&
   821       (src->n_samples_stop > src->n_samples) &&
  1045       (src->sample_stop < src->next_sample + samples)
   822       (src->n_samples_stop < src->n_samples + src->samples_per_buffer)
  1046       ) {
   823       ) {
  1047     /* calculate only partial buffer */
   824     /* calculate only partial buffer */
  1048     src->generate_samples_per_buffer = src->sample_stop - src->next_sample;
   825     src->generate_samples_per_buffer = src->n_samples_stop - src->n_samples;
  1049     next_sample = src->sample_stop;
   826     n_samples = src->n_samples_stop;
  1050     src->eos_reached = TRUE;
   827     src->eos_reached = TRUE;
  1051   } else {
   828   } else {
  1052     /* calculate full buffer */
   829     /* calculate full buffer */
  1053     src->generate_samples_per_buffer = samples;
   830     src->generate_samples_per_buffer = src->samples_per_buffer;
  1054     next_sample = src->next_sample + samples;
   831     n_samples = src->n_samples + src->samples_per_buffer;
  1055   }
   832   }
  1056 
   833   next_time = gst_util_uint64_scale (n_samples, GST_SECOND,
  1057   bytes = src->generate_samples_per_buffer * src->sample_size * src->channels;
   834       (guint64) src->samplerate);
  1058 
   835 
  1059   if ((res = gst_pad_alloc_buffer (basesrc->srcpad, src->next_sample,
   836   /* allocate a new buffer suitable for this pad */
  1060               bytes, GST_PAD_CAPS (basesrc->srcpad), &buf)) != GST_FLOW_OK) {
   837   switch (src->format) {
       
   838     case GST_AUDIO_TEST_SRC_FORMAT_S16:
       
   839       sample_size = sizeof (gint16);
       
   840       break;
       
   841     case GST_AUDIO_TEST_SRC_FORMAT_S32:
       
   842       sample_size = sizeof (gint32);
       
   843       break;
       
   844     case GST_AUDIO_TEST_SRC_FORMAT_F32:
       
   845       sample_size = sizeof (gfloat);
       
   846       break;
       
   847     case GST_AUDIO_TEST_SRC_FORMAT_F64:
       
   848       sample_size = sizeof (gdouble);
       
   849       break;
       
   850     default:
       
   851       sample_size = -1;
       
   852       GST_ELEMENT_ERROR (src, CORE, NEGOTIATION, (NULL),
       
   853           ("format wasn't negotiated before get function"));
       
   854       return GST_FLOW_NOT_NEGOTIATED;
       
   855       break;
       
   856   }
       
   857 
       
   858   if ((res = gst_pad_alloc_buffer (basesrc->srcpad, src->n_samples,
       
   859               src->generate_samples_per_buffer * sample_size,
       
   860               GST_PAD_CAPS (basesrc->srcpad), &buf)) != GST_FLOW_OK) {
  1061     return res;
   861     return res;
  1062   }
   862   }
  1063 
   863 
  1064   next_byte = src->next_byte + bytes;
   864   GST_BUFFER_TIMESTAMP (buf) = src->timestamp_offset + src->running_time;
  1065   next_time = gst_util_uint64_scale_int (next_sample, GST_SECOND,
   865   GST_BUFFER_OFFSET_END (buf) = n_samples;
  1066       src->samplerate);
   866   GST_BUFFER_DURATION (buf) = next_time - src->running_time;
  1067 
   867 
  1068   GST_LOG_OBJECT (src, "samplerate %d", src->samplerate);
   868   gst_object_sync_values (G_OBJECT (src), src->running_time);
  1069   GST_LOG_OBJECT (src, "next_sample %" G_GINT64_FORMAT ", ts %" GST_TIME_FORMAT,
   869 
  1070       next_sample, GST_TIME_ARGS (next_time));
   870   src->running_time = next_time;
  1071 
   871   src->n_samples = n_samples;
  1072   GST_BUFFER_TIMESTAMP (buf) = src->timestamp_offset + src->next_time;
       
  1073   GST_BUFFER_OFFSET (buf) = src->next_sample;
       
  1074   GST_BUFFER_OFFSET_END (buf) = next_sample;
       
  1075   GST_BUFFER_DURATION (buf) = next_time - src->next_time;
       
  1076 
       
  1077   gst_object_sync_values (G_OBJECT (src), src->next_time);
       
  1078 
       
  1079   src->next_time = next_time;
       
  1080   src->next_sample = next_sample;
       
  1081   src->next_byte = next_byte;
       
  1082 
   872 
  1083   GST_LOG_OBJECT (src, "generating %u samples at ts %" GST_TIME_FORMAT,
   873   GST_LOG_OBJECT (src, "generating %u samples at ts %" GST_TIME_FORMAT,
  1084       src->generate_samples_per_buffer,
   874       length, GST_TIME_ARGS (GST_BUFFER_TIMESTAMP (buf)));
  1085       GST_TIME_ARGS (GST_BUFFER_TIMESTAMP (buf)));
       
  1086 
   875 
  1087   src->process (src, GST_BUFFER_DATA (buf));
   876   src->process (src, GST_BUFFER_DATA (buf));
  1088 
   877 
  1089   if (G_UNLIKELY ((src->wave == GST_AUDIO_TEST_SRC_WAVE_SILENCE)
   878   if (G_UNLIKELY ((src->wave == GST_AUDIO_TEST_SRC_WAVE_SILENCE)
  1090           || (src->volume == 0.0))) {
   879           || (src->volume == 0.0))) {
  1121       gst_base_src_set_live (GST_BASE_SRC (src), g_value_get_boolean (value));
   910       gst_base_src_set_live (GST_BASE_SRC (src), g_value_get_boolean (value));
  1122       break;
   911       break;
  1123     case PROP_TIMESTAMP_OFFSET:
   912     case PROP_TIMESTAMP_OFFSET:
  1124       src->timestamp_offset = g_value_get_int64 (value);
   913       src->timestamp_offset = g_value_get_int64 (value);
  1125       break;
   914       break;
  1126     case PROP_CAN_ACTIVATE_PUSH:
       
  1127       GST_BASE_SRC (src)->can_activate_push = g_value_get_boolean (value);
       
  1128       break;
       
  1129     case PROP_CAN_ACTIVATE_PULL:
       
  1130       src->can_activate_pull = g_value_get_boolean (value);
       
  1131       break;
       
  1132     default:
   915     default:
  1133       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
   916       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
  1134       break;
   917       break;
  1135   }
   918   }
  1136 }
   919 }
  1157     case PROP_IS_LIVE:
   940     case PROP_IS_LIVE:
  1158       g_value_set_boolean (value, gst_base_src_is_live (GST_BASE_SRC (src)));
   941       g_value_set_boolean (value, gst_base_src_is_live (GST_BASE_SRC (src)));
  1159       break;
   942       break;
  1160     case PROP_TIMESTAMP_OFFSET:
   943     case PROP_TIMESTAMP_OFFSET:
  1161       g_value_set_int64 (value, src->timestamp_offset);
   944       g_value_set_int64 (value, src->timestamp_offset);
  1162       break;
       
  1163     case PROP_CAN_ACTIVATE_PUSH:
       
  1164       g_value_set_boolean (value, GST_BASE_SRC (src)->can_activate_push);
       
  1165       break;
       
  1166     case PROP_CAN_ACTIVATE_PULL:
       
  1167       g_value_set_boolean (value, src->can_activate_pull);
       
  1168       break;
   945       break;
  1169     default:
   946     default:
  1170       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
   947       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
  1171       break;
   948       break;
  1172   }
   949   }