expand tabs
[platform/upstream/gstreamer.git] / gst-libs / gst / audio / gstaudiosrc.c
1 /* GStreamer
2  * Copyright (C) 1999,2000 Erik Walthinsen <omega@cse.ogi.edu>
3  *                    2005 Wim Taymans <wim@fluendo.com>
4  *
5  * gstaudiosrc.c: simple audio src base class
6  *
7  * This library is free software; you can redistribute it and/or
8  * modify it under the terms of the GNU Library General Public
9  * License as published by the Free Software Foundation; either
10  * version 2 of the License, or (at your option) any later version.
11  *
12  * This library is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15  * Library General Public License for more details.
16  *
17  * You should have received a copy of the GNU Library General Public
18  * License along with this library; if not, write to the
19  * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
20  * Boston, MA 02111-1307, USA.
21  */
22
23 #include <string.h>
24
25 #include "gstaudiosrc.h"
26
27 GST_DEBUG_CATEGORY_STATIC (gst_audio_src_debug);
28 #define GST_CAT_DEFAULT gst_audio_src_debug
29
30 #define GST_TYPE_AUDIORING_BUFFER        \
31         (gst_audioringbuffer_get_type())
32 #define GST_AUDIORING_BUFFER(obj)        \
33         (G_TYPE_CHECK_INSTANCE_CAST((obj),GST_TYPE_AUDIORING_BUFFER,GstAudioRingBuffer))
34 #define GST_AUDIORING_BUFFER_CLASS(klass) \
35         (G_TYPE_CHECK_CLASS_CAST((klass),GST_TYPE_AUDIORING_BUFFER,GstAudioRingBufferClass))
36 #define GST_AUDIORING_BUFFER_GET_CLASS(obj) \
37         (G_TYPE_INSTANCE_GET_CLASS ((obj), GST_TYPE_AUDIORING_BUFFER, GstAudioRingBufferClass))
38 #define GST_IS_AUDIORING_BUFFER(obj)     \
39         (G_TYPE_CHECK_INSTANCE_TYPE((obj),GST_TYPE_AUDIORING_BUFFER))
40 #define GST_IS_AUDIORING_BUFFER_CLASS(obj)\
41         (G_TYPE_CHECK_CLASS_TYPE((klass),GST_TYPE_AUDIORING_BUFFER))
42
43 typedef struct _GstAudioRingBuffer GstAudioRingBuffer;
44 typedef struct _GstAudioRingBufferClass GstAudioRingBufferClass;
45
46 #define GST_AUDIORING_BUFFER_GET_COND(buf) (((GstAudioRingBuffer *)buf)->cond)
47 #define GST_AUDIORING_BUFFER_WAIT(buf)     (g_cond_wait (GST_AUDIORING_BUFFER_GET_COND (buf), GST_OBJECT_GET_LOCK (buf)))
48 #define GST_AUDIORING_BUFFER_SIGNAL(buf)   (g_cond_signal (GST_AUDIORING_BUFFER_GET_COND (buf)))
49 #define GST_AUDIORING_BUFFER_BROADCAST(buf)(g_cond_broadcast (GST_AUDIORING_BUFFER_GET_COND (buf)))
50
51 struct _GstAudioRingBuffer
52 {
53   GstRingBuffer object;
54
55   gboolean running;
56   gint queuedseg;
57
58   GCond *cond;
59 };
60
61 struct _GstAudioRingBufferClass
62 {
63   GstRingBufferClass parent_class;
64 };
65
66 static void gst_audioringbuffer_class_init (GstAudioRingBufferClass * klass);
67 static void gst_audioringbuffer_init (GstAudioRingBuffer * ringbuffer,
68     GstAudioRingBufferClass * klass);
69 static void gst_audioringbuffer_dispose (GObject * object);
70 static void gst_audioringbuffer_finalize (GObject * object);
71
72 static GstRingBufferClass *ring_parent_class = NULL;
73
74 static gboolean gst_audioringbuffer_open_device (GstRingBuffer * buf);
75 static gboolean gst_audioringbuffer_close_device (GstRingBuffer * buf);
76 static gboolean gst_audioringbuffer_acquire (GstRingBuffer * buf,
77     GstRingBufferSpec * spec);
78 static gboolean gst_audioringbuffer_release (GstRingBuffer * buf);
79 static gboolean gst_audioringbuffer_start (GstRingBuffer * buf);
80 static gboolean gst_audioringbuffer_stop (GstRingBuffer * buf);
81 static guint gst_audioringbuffer_delay (GstRingBuffer * buf);
82
83 /* ringbuffer abstract base class */
84 static GType
85 gst_audioringbuffer_get_type (void)
86 {
87   static GType ringbuffer_type = 0;
88
89   if (!ringbuffer_type) {
90     static const GTypeInfo ringbuffer_info = {
91       sizeof (GstAudioRingBufferClass),
92       NULL,
93       NULL,
94       (GClassInitFunc) gst_audioringbuffer_class_init,
95       NULL,
96       NULL,
97       sizeof (GstAudioRingBuffer),
98       0,
99       (GInstanceInitFunc) gst_audioringbuffer_init,
100       NULL
101     };
102
103     ringbuffer_type =
104         g_type_register_static (GST_TYPE_RING_BUFFER, "GstAudioSrcRingBuffer",
105         &ringbuffer_info, 0);
106   }
107   return ringbuffer_type;
108 }
109
110 static void
111 gst_audioringbuffer_class_init (GstAudioRingBufferClass * klass)
112 {
113   GObjectClass *gobject_class;
114   GstObjectClass *gstobject_class;
115   GstRingBufferClass *gstringbuffer_class;
116
117   gobject_class = (GObjectClass *) klass;
118   gstobject_class = (GstObjectClass *) klass;
119   gstringbuffer_class = (GstRingBufferClass *) klass;
120
121   ring_parent_class = g_type_class_ref (GST_TYPE_RING_BUFFER);
122
123   gobject_class->dispose = GST_DEBUG_FUNCPTR (gst_audioringbuffer_dispose);
124   gobject_class->finalize = GST_DEBUG_FUNCPTR (gst_audioringbuffer_finalize);
125
126   gstringbuffer_class->open_device =
127       GST_DEBUG_FUNCPTR (gst_audioringbuffer_open_device);
128   gstringbuffer_class->close_device =
129       GST_DEBUG_FUNCPTR (gst_audioringbuffer_close_device);
130   gstringbuffer_class->acquire =
131       GST_DEBUG_FUNCPTR (gst_audioringbuffer_acquire);
132   gstringbuffer_class->release =
133       GST_DEBUG_FUNCPTR (gst_audioringbuffer_release);
134   gstringbuffer_class->start = GST_DEBUG_FUNCPTR (gst_audioringbuffer_start);
135   gstringbuffer_class->resume = GST_DEBUG_FUNCPTR (gst_audioringbuffer_start);
136   gstringbuffer_class->stop = GST_DEBUG_FUNCPTR (gst_audioringbuffer_stop);
137
138   gstringbuffer_class->delay = GST_DEBUG_FUNCPTR (gst_audioringbuffer_delay);
139 }
140
141 typedef guint (*ReadFunc) (GstAudioSrc * src, gpointer data, guint length);
142
143 /* this internal thread does nothing else but read samples from the audio device.
144  * It will read each segment in the ringbuffer and will update the play
145  * pointer. 
146  * The start/stop methods control the thread.
147  */
148 static void
149 audioringbuffer_thread_func (GstRingBuffer * buf)
150 {
151   GstAudioSrc *src;
152   GstAudioSrcClass *csrc;
153   GstAudioRingBuffer *abuf = GST_AUDIORING_BUFFER (buf);
154   ReadFunc readfunc;
155
156   src = GST_AUDIO_SRC (GST_OBJECT_PARENT (buf));
157   csrc = GST_AUDIO_SRC_GET_CLASS (src);
158
159   GST_DEBUG ("enter thread");
160
161   readfunc = csrc->read;
162   if (readfunc == NULL)
163     goto no_function;
164
165   while (TRUE) {
166     gint left, len;
167     guint8 *readptr;
168     gint readseg;
169
170     if (gst_ring_buffer_prepare_read (buf, &readseg, &readptr, &len)) {
171       gint read = 0;
172
173       left = len;
174       do {
175         GST_DEBUG ("transfer %d bytes to segment %d", left, readseg);
176         read = readfunc (src, readptr + read, left);
177         GST_DEBUG ("transfered %d bytes", read);
178         if (read < 0 || read > left) {
179           GST_WARNING ("error reading data (reason: %s), skipping segment\n",
180               strerror (errno));
181           break;
182         }
183         left -= read;
184       } while (left > 0);
185
186       /* we read one segment */
187       gst_ring_buffer_advance (buf, 1);
188     } else {
189       GST_OBJECT_LOCK (abuf);
190       if (!abuf->running)
191         goto stop_running;
192       GST_DEBUG ("signal wait");
193       GST_AUDIORING_BUFFER_SIGNAL (buf);
194       GST_DEBUG ("wait for action");
195       GST_AUDIORING_BUFFER_WAIT (buf);
196       GST_DEBUG ("got signal");
197       if (!abuf->running)
198         goto stop_running;
199       GST_DEBUG ("continue running");
200       GST_OBJECT_UNLOCK (abuf);
201     }
202   }
203   GST_DEBUG ("exit thread");
204
205   return;
206
207   /* ERROR */
208 no_function:
209   {
210     GST_DEBUG ("no write function, exit thread");
211     return;
212   }
213 stop_running:
214   {
215     GST_OBJECT_UNLOCK (abuf);
216     GST_DEBUG ("stop running, exit thread");
217     return;
218   }
219 }
220
221 static void
222 gst_audioringbuffer_init (GstAudioRingBuffer * ringbuffer,
223     GstAudioRingBufferClass * g_class)
224 {
225   ringbuffer->running = FALSE;
226   ringbuffer->queuedseg = 0;
227
228   ringbuffer->cond = g_cond_new ();
229 }
230
231 static void
232 gst_audioringbuffer_dispose (GObject * object)
233 {
234   G_OBJECT_CLASS (ring_parent_class)->dispose (object);
235 }
236
237 static void
238 gst_audioringbuffer_finalize (GObject * object)
239 {
240   G_OBJECT_CLASS (ring_parent_class)->finalize (object);
241 }
242
243 static gboolean
244 gst_audioringbuffer_open_device (GstRingBuffer * buf)
245 {
246   GstAudioSrc *src;
247   GstAudioSrcClass *csrc;
248   gboolean result = TRUE;
249
250   src = GST_AUDIO_SRC (GST_OBJECT_PARENT (buf));
251   csrc = GST_AUDIO_SRC_GET_CLASS (src);
252
253   if (csrc->open)
254     result = csrc->open (src);
255
256   if (!result)
257     goto could_not_open;
258
259   return result;
260
261 could_not_open:
262   {
263     return FALSE;
264   }
265 }
266
267 static gboolean
268 gst_audioringbuffer_close_device (GstRingBuffer * buf)
269 {
270   GstAudioSrc *src;
271   GstAudioSrcClass *csrc;
272   gboolean result = TRUE;
273
274   src = GST_AUDIO_SRC (GST_OBJECT_PARENT (buf));
275   csrc = GST_AUDIO_SRC_GET_CLASS (src);
276
277   if (csrc->close)
278     result = csrc->close (src);
279
280   if (!result)
281     goto could_not_open;
282
283   return result;
284
285 could_not_open:
286   {
287     return FALSE;
288   }
289 }
290
291 static gboolean
292 gst_audioringbuffer_acquire (GstRingBuffer * buf, GstRingBufferSpec * spec)
293 {
294   GstAudioSrc *src;
295   GstAudioSrcClass *csrc;
296   GstAudioRingBuffer *abuf;
297   gboolean result = FALSE;
298
299   src = GST_AUDIO_SRC (GST_OBJECT_PARENT (buf));
300   csrc = GST_AUDIO_SRC_GET_CLASS (src);
301
302   if (csrc->prepare)
303     result = csrc->prepare (src, spec);
304
305   if (!result)
306     goto could_not_open;
307
308   /* allocate one more segment as we need some headroom */
309   spec->segtotal++;
310
311   buf->data = gst_buffer_new_and_alloc (spec->segtotal * spec->segsize);
312   memset (GST_BUFFER_DATA (buf->data), 0, GST_BUFFER_SIZE (buf->data));
313
314   abuf = GST_AUDIORING_BUFFER (buf);
315   abuf->running = TRUE;
316
317   src->thread =
318       g_thread_create ((GThreadFunc) audioringbuffer_thread_func, buf, TRUE,
319       NULL);
320   GST_AUDIORING_BUFFER_WAIT (buf);
321
322   return result;
323
324 could_not_open:
325   {
326     return FALSE;
327   }
328 }
329
330 /* function is called with LOCK */
331 static gboolean
332 gst_audioringbuffer_release (GstRingBuffer * buf)
333 {
334   GstAudioSrc *src;
335   GstAudioSrcClass *csrc;
336   GstAudioRingBuffer *abuf;
337   gboolean result = FALSE;
338
339   src = GST_AUDIO_SRC (GST_OBJECT_PARENT (buf));
340   csrc = GST_AUDIO_SRC_GET_CLASS (src);
341   abuf = GST_AUDIORING_BUFFER (buf);
342
343   abuf->running = FALSE;
344   GST_AUDIORING_BUFFER_SIGNAL (buf);
345   GST_OBJECT_UNLOCK (buf);
346
347   /* join the thread */
348   g_thread_join (src->thread);
349
350   GST_OBJECT_LOCK (buf);
351
352   /* free the buffer */
353   gst_buffer_unref (buf->data);
354   buf->data = NULL;
355
356   if (csrc->unprepare)
357     result = csrc->unprepare (src);
358
359   return result;
360 }
361
362 static gboolean
363 gst_audioringbuffer_start (GstRingBuffer * buf)
364 {
365   GstAudioSrc *src;
366
367   src = GST_AUDIO_SRC (GST_OBJECT_PARENT (buf));
368
369   GST_DEBUG ("start, sending signal");
370   GST_AUDIORING_BUFFER_SIGNAL (buf);
371
372   return TRUE;
373 }
374
375 static gboolean
376 gst_audioringbuffer_stop (GstRingBuffer * buf)
377 {
378   GstAudioSrc *src;
379   GstAudioSrcClass *csrc;
380
381   src = GST_AUDIO_SRC (GST_OBJECT_PARENT (buf));
382   csrc = GST_AUDIO_SRC_GET_CLASS (src);
383
384   /* unblock any pending writes to the audio device */
385   if (csrc->reset) {
386     GST_DEBUG ("reset...");
387     csrc->reset (src);
388     GST_DEBUG ("reset done");
389   }
390
391   GST_DEBUG ("stop, waiting...");
392   GST_AUDIORING_BUFFER_WAIT (buf);
393   GST_DEBUG ("stoped");
394
395   return TRUE;
396 }
397
398 static guint
399 gst_audioringbuffer_delay (GstRingBuffer * buf)
400 {
401   GstAudioSrc *src;
402   GstAudioSrcClass *csrc;
403   guint res = 0;
404
405   src = GST_AUDIO_SRC (GST_OBJECT_PARENT (buf));
406   csrc = GST_AUDIO_SRC_GET_CLASS (src);
407
408   if (csrc->delay)
409     res = csrc->delay (src);
410
411   return res;
412 }
413
414 /* AudioSrc signals and args */
415 enum
416 {
417   /* FILL ME */
418   LAST_SIGNAL
419 };
420
421 enum
422 {
423   ARG_0,
424 };
425
426 #define _do_init(bla) \
427     GST_DEBUG_CATEGORY_INIT (gst_audio_src_debug, "audiosrc", 0, "audiosrc element");
428
429 GST_BOILERPLATE_FULL (GstAudioSrc, gst_audio_src, GstBaseAudioSrc,
430     GST_TYPE_BASE_AUDIO_SRC, _do_init);
431
432 static GstRingBuffer *gst_audio_src_create_ringbuffer (GstBaseAudioSrc * src);
433
434 static void
435 gst_audio_src_base_init (gpointer g_class)
436 {
437 }
438
439 static void
440 gst_audio_src_class_init (GstAudioSrcClass * klass)
441 {
442   GObjectClass *gobject_class;
443   GstElementClass *gstelement_class;
444   GstBaseSrcClass *gstbasesrc_class;
445   GstPushSrcClass *gstpushsrc_class;
446   GstBaseAudioSrcClass *gstbaseaudiosrc_class;
447
448   gobject_class = (GObjectClass *) klass;
449   gstelement_class = (GstElementClass *) klass;
450   gstbasesrc_class = (GstBaseSrcClass *) klass;
451   gstpushsrc_class = (GstPushSrcClass *) klass;
452   gstbaseaudiosrc_class = (GstBaseAudioSrcClass *) klass;
453
454   gstbaseaudiosrc_class->create_ringbuffer =
455       GST_DEBUG_FUNCPTR (gst_audio_src_create_ringbuffer);
456 }
457
458 static void
459 gst_audio_src_init (GstAudioSrc * audiosrc, GstAudioSrcClass * g_class)
460 {
461   gst_base_src_set_live (GST_BASE_SRC (audiosrc), TRUE);
462 }
463
464 static GstRingBuffer *
465 gst_audio_src_create_ringbuffer (GstBaseAudioSrc * src)
466 {
467   GstRingBuffer *buffer;
468
469   GST_DEBUG ("creating ringbuffer");
470   buffer = g_object_new (GST_TYPE_AUDIORING_BUFFER, NULL);
471   GST_DEBUG ("created ringbuffer @%p", buffer);
472
473   return buffer;
474 }