Added gst-plugins-base-subtitles0.10-0.10.34 for Meego Harmattan 1.2
[mafwsubrenderer] / gst-plugins-base-subtitles0.10 / tests / old / testsuite / alsa / sinesrc.c
1 /*
2  * Copyright (C) 2003 Benjamin Otte <in7y118@public.uni-hamburg.de>
3  *
4  * sinesrc.c: An elemnt emitting a sine src in lots of different formats
5  *
6  * This library is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU General Public
8  * License as published by the Free Software Foundation; either
9  * version 2 of the License, or (at your option) any later version.
10  *
11  * This library is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14  * General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public
17  * License along with this library; if not, write to the Free
18  * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
19  */
20
21 #include "sinesrc.h"
22 #include <math.h>
23 #include <string.h>             /* memcpy */
24
25 #define SAMPLES_PER_WAVE 200
26
27 static GstStaticPadTemplate sinesrc_src_factory =
28     GST_STATIC_PAD_TEMPLATE ("src",
29     GST_PAD_SRC,
30     GST_PAD_ALWAYS,
31     GST_STATIC_CAPS ("audio/x-raw-int, "
32         "endianness = (int) { LITTLE_ENDIAN, BIG_ENDIAN }, "
33         "signed = (boolean) { FALSE, TRUE }, "
34         "width = (int) [8, 32], "
35         "depth = (int) [8, 32], "
36         "rate = (int) [8000, 192000], "
37         "channels = (int) [1, 16];"
38         "audio/x-raw-float, "
39         "endianness = (int) BYTE_ORDER, "
40         "width = (int) {32, 64}, "
41         "rate = (int) [8000, 192000], " "channels = (int) [1, 16]")
42     );
43
44 static GstElementClass *parent_class = NULL;
45
46 static void sinesrc_init (SineSrc * src);
47 static void sinesrc_class_init (SineSrcClass * klass);
48
49 static GstData *sinesrc_get (GstPad * pad);
50 static GstStateChangeReturn sinesrc_change_state (GstElement * element,
51     GstStateChange transition);
52
53
54 GType
55 sinesrc_get_type (void)
56 {
57   static GType sinesrc_type = 0;
58
59   if (!sinesrc_type) {
60     static const GTypeInfo sinesrc_info = {
61       sizeof (SineSrcClass), NULL, NULL,
62       (GClassInitFunc) sinesrc_class_init, NULL, NULL,
63       sizeof (SineSrc), 0,
64       (GInstanceInitFunc) sinesrc_init,
65     };
66
67     sinesrc_type = g_type_register_static (GST_TYPE_ELEMENT, "SineSrc",
68         &sinesrc_info, 0);
69   }
70   return sinesrc_type;
71 }
72
73 static void
74 sinesrc_class_init (SineSrcClass * klass)
75 {
76   GstElementClass *element_class = GST_ELEMENT_CLASS (klass);
77
78   element_class->change_state = sinesrc_change_state;
79
80   parent_class = g_type_class_peek_parent (klass);
81 }
82
83 static void
84 sinesrc_init (SineSrc * src)
85 {
86   src->src =
87       gst_pad_new_from_template (gst_static_pad_template_get
88       (&sinesrc_src_factory), "src");
89   gst_element_add_pad (GST_ELEMENT (src), src->src);
90   gst_pad_set_get_function (src->src, sinesrc_get);
91
92   src->width = 16;
93   src->depth = 16;
94   src->sign = TRUE;
95   src->endianness = G_BYTE_ORDER;
96   src->rate = 44100;
97   src->channels = 1;
98   src->type = SINE_SRC_INT;
99   src->newcaps = TRUE;
100
101   src->pre_get_func = NULL;
102
103   GST_OBJECT (src)->name = "sinesrc";
104 }
105
106 static void
107 sinesrc_force_caps (SineSrc * src)
108 {
109   GstCaps *caps;
110
111   if (!src->newcaps)
112     return;
113
114   src->newcaps = FALSE;
115
116   switch (src->type) {
117     case SINE_SRC_INT:
118       caps = gst_caps_new_simple ("audio/x-raw-int",
119           "signed", G_TYPE_BOOLEAN, src->sign,
120           "depth", G_TYPE_INT, src->depth, NULL);
121       if (src->width > 8)
122         gst_caps_set_simple (caps,
123             "endianness", G_TYPE_INT, src->endianness, NULL);
124       break;
125     case SINE_SRC_FLOAT:
126       g_assert (src->width == 32 || src->width == 64);
127       caps = gst_caps_new_simple ("audio/x-raw-float",
128           "endianness", G_TYPE_INT, src->endianness, NULL);
129       break;
130     default:
131       caps = NULL;
132       g_assert_not_reached ();
133   }
134   gst_caps_set_simple (caps,
135       "width", G_TYPE_INT, src->width,
136       "rate", G_TYPE_INT, src->rate,
137       "channels", G_TYPE_INT, src->channels, NULL);
138
139   if (gst_pad_try_set_caps (src->src, caps) != GST_PAD_LINK_OK)
140     g_assert_not_reached ();
141 }
142
143 /* always return 1 wave 
144  * there are 200 waves in 1 second, so the frequency is samplerate/200
145  */
146 static guint8
147 UIDENTITY (guint8 x)
148 {
149   return x;
150 };
151
152 static gint8
153 IDENTITY (gint8 x)
154 {
155   return x;
156 };
157
158 #define POPULATE(format, be_func, le_func) G_STMT_START {\
159   format val = (format) int_value;\
160   format *p = data;\
161   switch (src->endianness) {\
162     case G_LITTLE_ENDIAN:\
163       val = le_func (val);\
164       break;\
165     case G_BIG_ENDIAN:\
166       val = be_func (val);\
167       break;\
168     default: \
169       g_assert_not_reached ();\
170   };\
171   for (j = 0; j < src->channels; j++) {\
172     *p = val;\
173     p ++;\
174   }\
175   data = p;\
176 } G_STMT_END
177
178 static GstData *
179 sinesrc_get (GstPad * pad)
180 {
181   GstBuffer *buf;
182   SineSrc *src;
183
184   void *data;
185   gint i, j;
186   gdouble value;
187
188   g_return_val_if_fail (pad != NULL, NULL);
189   src = SINESRC (gst_pad_get_parent (pad));
190
191   if (src->pre_get_func)
192     src->pre_get_func (src);
193
194   buf = gst_buffer_new_and_alloc ((src->width / 8) * src->channels *
195       SAMPLES_PER_WAVE);
196   g_assert (buf);
197   data = GST_BUFFER_DATA (buf);
198   g_assert (data);
199
200   for (i = 0; i < SAMPLES_PER_WAVE; i++) {
201     value = sin (i * 2 * M_PI / SAMPLES_PER_WAVE);
202     switch (src->type) {
203       case SINE_SRC_INT:{
204         gint64 int_value =
205             (value + (src->sign ? 0 : 1)) * (((guint64) 1) << (src->depth - 1));
206         if (int_value ==
207             (1 + (src->sign ? 0 : 1)) * (((guint64) 1) << (src->depth - 1)))
208           int_value--;
209         switch (src->width) {
210           case 8:
211             if (src->sign)
212               POPULATE (gint8, IDENTITY, IDENTITY);
213             else
214               POPULATE (guint8, UIDENTITY, UIDENTITY);
215             break;
216           case 16:
217             if (src->sign)
218               POPULATE (gint16, GINT16_TO_BE, GINT16_TO_LE);
219             else
220               POPULATE (guint16, GUINT16_TO_BE, GUINT16_TO_LE);
221             break;
222           case 24:
223             if (src->sign) {
224               gpointer p;
225               gint32 val = (gint32) int_value;
226
227               switch (src->endianness) {
228                 case G_LITTLE_ENDIAN:
229                   val = GINT32_TO_LE (val);
230                   break;
231                 case G_BIG_ENDIAN:
232                   val = GINT32_TO_BE (val);
233                   break;
234                 default:
235                   g_assert_not_reached ();
236               };
237               p = &val;
238               if (src->endianness == G_BIG_ENDIAN)
239                 p++;
240               for (j = 0; j < src->channels; j++) {
241                 memcpy (data, p, 3);
242                 data += 3;
243               }
244             } else {
245               gpointer p;
246               guint32 val = (guint32) int_value;
247
248               switch (src->endianness) {
249                 case G_LITTLE_ENDIAN:
250                   val = GUINT32_TO_LE (val);
251                   break;
252                 case G_BIG_ENDIAN:
253                   val = GUINT32_TO_BE (val);
254                   break;
255                 default:
256                   g_assert_not_reached ();
257               };
258               p = &val;
259               if (src->endianness == G_BIG_ENDIAN)
260                 p++;
261               for (j = 0; j < src->channels; j++) {
262                 memcpy (data, p, 3);
263                 data += 3;
264               }
265             }
266             break;
267           case 32:
268             if (src->sign)
269               POPULATE (gint32, GINT32_TO_BE, GINT32_TO_LE);
270             else
271               POPULATE (guint32, GUINT32_TO_BE, GUINT32_TO_LE);
272             break;
273           default:
274             g_assert_not_reached ();
275         }
276         break;
277       }
278       case SINE_SRC_FLOAT:
279         if (src->width == 32) {
280           gfloat *p = (gfloat *) data;
281           gfloat fval = (gfloat) value;
282
283           for (j = 0; j < src->channels; j++) {
284             *p = fval;
285             p++;
286           }
287           data = p;
288           break;
289         }
290         if (src->width == 64) {
291           gdouble *p = (gdouble *) data;
292
293           for (j = 0; j < src->channels; j++) {
294             *p = value;
295             p++;
296           }
297           data = p;
298           break;
299         }
300         g_assert_not_reached ();
301       default:
302         g_assert_not_reached ();
303     }
304   }
305
306   if (src->newcaps) {
307     sinesrc_force_caps (src);
308   }
309   return GST_DATA (buf);
310 }
311
312 GstElement *
313 sinesrc_new (void)
314 {
315   return GST_ELEMENT (g_object_new (TYPE_SINESRC, NULL));
316 }
317
318 void
319 sinesrc_set_pre_get_func (SineSrc * src, PreGetFunc func)
320 {
321   src->pre_get_func = func;
322 }
323
324 static GstStateChangeReturn
325 sinesrc_change_state (GstElement * element, GstStateChange transition)
326 {
327   SineSrc *sinesrc;
328
329   g_return_val_if_fail (element != NULL, FALSE);
330   sinesrc = SINESRC (element);
331
332   switch (transition) {
333     case GST_STATE_CHANGE_NULL_TO_READY:
334     case GST_STATE_CHANGE_READY_TO_PAUSED:
335     case GST_STATE_CHANGE_PAUSED_TO_PLAYING:
336     case GST_STATE_CHANGE_PLAYING_TO_PAUSED:
337       break;
338     case GST_STATE_CHANGE_PAUSED_TO_READY:
339       sinesrc->newcaps = TRUE;
340       break;
341     case GST_STATE_CHANGE_READY_TO_NULL:
342       break;
343     default:
344       g_assert_not_reached ();
345   }
346
347   if (GST_ELEMENT_CLASS (parent_class)->change_state)
348     return GST_ELEMENT_CLASS (parent_class)->change_state (element, transition);
349
350   return GST_STATE_CHANGE_SUCCESS;
351 }