expand tabs
[platform/upstream/gstreamer.git] / ext / alsa / gstalsasrc.c
1 /* GStreamer
2  * Copyright (C) 2005 Wim Taymans <wim@fluendo.com>
3  *
4  * gstalsasrc.c:
5  *
6  * This library is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU Library 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  * Library General Public License for more details.
15  *
16  * You should have received a copy of the GNU Library General Public
17  * License along with this library; if not, write to the
18  * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
19  * Boston, MA 02111-1307, USA.
20  */
21
22 #ifdef HAVE_CONFIG_H
23 #include "config.h"
24 #endif
25 #include <sys/ioctl.h>
26 #include <fcntl.h>
27 #include <errno.h>
28 #include <unistd.h>
29 #include <string.h>
30 #include <getopt.h>
31 #include <alsa/asoundlib.h>
32
33
34 #include "gstalsasrc.h"
35
36 /* elementfactory information */
37 static GstElementDetails gst_alsasrc_details =
38 GST_ELEMENT_DETAILS ("Audio Src (ALSA)",
39     "Src/Audio",
40     "Output to a sound card via ALSA",
41     "Wim Taymans <wim@fluendo.com>");
42
43 enum
44 {
45   PROP_0,
46   PROP_DEVICE,
47   PROP_DEVICE_NAME,
48 };
49
50 GST_BOILERPLATE_WITH_INTERFACE (GstAlsaSrc, gst_alsasrc, GstAudioSrc,
51     GST_TYPE_AUDIO_SRC, GstMixer, GST_TYPE_MIXER, gst_alsasrc_mixer);
52
53 GST_IMPLEMENT_ALSA_MIXER_METHODS (GstAlsaSrc, gst_alsasrc_mixer);
54
55 static void gst_alsasrc_dispose (GObject * object);
56 static void gst_alsasrc_set_property (GObject * object,
57     guint prop_id, const GValue * value, GParamSpec * pspec);
58 static void gst_alsasrc_get_property (GObject * object,
59     guint prop_id, GValue * value, GParamSpec * pspec);
60
61 static GstCaps *gst_alsasrc_getcaps (GstBaseSrc * bsrc);
62
63 static gboolean gst_alsasrc_open (GstAudioSrc * asrc);
64 static gboolean gst_alsasrc_prepare (GstAudioSrc * asrc,
65     GstRingBufferSpec * spec);
66 static gboolean gst_alsasrc_unprepare (GstAudioSrc * asrc);
67 static gboolean gst_alsasrc_close (GstAudioSrc * asrc);
68 static guint gst_alsasrc_read (GstAudioSrc * asrc, gpointer data, guint length);
69 static guint gst_alsasrc_delay (GstAudioSrc * asrc);
70 static void gst_alsasrc_reset (GstAudioSrc * asrc);
71
72 /* AlsaSrc signals and args */
73 enum
74 {
75   LAST_SIGNAL
76 };
77
78 static GstStaticPadTemplate alsasrc_src_factory =
79     GST_STATIC_PAD_TEMPLATE ("src",
80     GST_PAD_SRC,
81     GST_PAD_ALWAYS,
82     GST_STATIC_CAPS ("audio/x-raw-int, "
83         "endianness = (int) { LITTLE_ENDIAN, BIG_ENDIAN }, "
84         "signed = (boolean) { TRUE, FALSE }, "
85         "width = (int) 16, "
86         "depth = (int) 16, "
87         "rate = (int) [ 1, MAX ], " "channels = (int) [ 1, 2 ]; "
88         "audio/x-raw-int, "
89         "signed = (boolean) { TRUE, FALSE }, "
90         "width = (int) 8, "
91         "depth = (int) 8, "
92         "rate = (int) [ 1, MAX ], " "channels = (int) [ 1, 2 ]")
93     );
94
95 static void
96 gst_alsasrc_dispose (GObject * object)
97 {
98   G_OBJECT_CLASS (parent_class)->dispose (object);
99 }
100
101 static void
102 gst_alsasrc_base_init (gpointer g_class)
103 {
104   GstElementClass *element_class = GST_ELEMENT_CLASS (g_class);
105
106   gst_element_class_set_details (element_class, &gst_alsasrc_details);
107
108   gst_element_class_add_pad_template (element_class,
109       gst_static_pad_template_get (&alsasrc_src_factory));
110 }
111
112 static void
113 gst_alsasrc_class_init (GstAlsaSrcClass * klass)
114 {
115   GObjectClass *gobject_class;
116   GstElementClass *gstelement_class;
117   GstBaseSrcClass *gstbasesrc_class;
118   GstBaseAudioSrcClass *gstbaseaudiosrc_class;
119   GstAudioSrcClass *gstaudiosrc_class;
120
121   gobject_class = (GObjectClass *) klass;
122   gstelement_class = (GstElementClass *) klass;
123   gstbasesrc_class = (GstBaseSrcClass *) klass;
124   gstbaseaudiosrc_class = (GstBaseAudioSrcClass *) klass;
125   gstaudiosrc_class = (GstAudioSrcClass *) klass;
126
127   gobject_class->dispose = GST_DEBUG_FUNCPTR (gst_alsasrc_dispose);
128   gobject_class->get_property = GST_DEBUG_FUNCPTR (gst_alsasrc_get_property);
129   gobject_class->set_property = GST_DEBUG_FUNCPTR (gst_alsasrc_set_property);
130
131   gstbasesrc_class->get_caps = GST_DEBUG_FUNCPTR (gst_alsasrc_getcaps);
132
133   gstaudiosrc_class->open = GST_DEBUG_FUNCPTR (gst_alsasrc_open);
134   gstaudiosrc_class->prepare = GST_DEBUG_FUNCPTR (gst_alsasrc_prepare);
135   gstaudiosrc_class->unprepare = GST_DEBUG_FUNCPTR (gst_alsasrc_unprepare);
136   gstaudiosrc_class->close = GST_DEBUG_FUNCPTR (gst_alsasrc_close);
137   gstaudiosrc_class->read = GST_DEBUG_FUNCPTR (gst_alsasrc_read);
138   gstaudiosrc_class->delay = GST_DEBUG_FUNCPTR (gst_alsasrc_delay);
139   gstaudiosrc_class->reset = GST_DEBUG_FUNCPTR (gst_alsasrc_reset);
140
141   g_object_class_install_property (gobject_class, PROP_DEVICE,
142       g_param_spec_string ("device", "Device",
143           "ALSA device, as defined in an asound configuration file",
144           "default", G_PARAM_READWRITE));
145
146   g_object_class_install_property (gobject_class, PROP_DEVICE_NAME,
147       g_param_spec_string ("device-name", "Device name",
148           "Human-readable name of the sound device", "", G_PARAM_READABLE));
149 }
150
151 static void
152 gst_alsasrc_set_property (GObject * object, guint prop_id,
153     const GValue * value, GParamSpec * pspec)
154 {
155   GstAlsaSrc *src;
156
157   src = GST_ALSA_SRC (object);
158
159   switch (prop_id) {
160     case PROP_DEVICE:
161       if (src->device)
162         g_free (src->device);
163       src->device = g_strdup (g_value_get_string (value));
164       break;
165     default:
166       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
167       break;
168   }
169 }
170
171 static void
172 gst_alsasrc_get_property (GObject * object, guint prop_id,
173     GValue * value, GParamSpec * pspec)
174 {
175   GstAlsaSrc *src;
176
177   src = GST_ALSA_SRC (object);
178
179   switch (prop_id) {
180     case PROP_DEVICE:
181       g_value_set_string (value, src->device);
182       break;
183     case PROP_DEVICE_NAME:
184       if (src->handle) {
185         snd_pcm_info_t *info;
186
187         snd_pcm_info_malloc (&info);
188         snd_pcm_info (src->handle, info);
189         g_value_set_string (value, snd_pcm_info_get_name (info));
190         snd_pcm_info_free (info);
191       } else {
192         g_value_set_string (value, NULL);
193       }
194       break;
195     default:
196       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
197       break;
198   }
199 }
200
201 static void
202 gst_alsasrc_init (GstAlsaSrc * alsasrc, GstAlsaSrcClass * g_class)
203 {
204   GST_DEBUG ("initializing alsasrc");
205
206   alsasrc->device = g_strdup ("default");
207 }
208
209 static GstCaps *
210 gst_alsasrc_getcaps (GstBaseSrc * bsrc)
211 {
212   return NULL;
213 }
214
215 #define CHECK(call, error) \
216 G_STMT_START {                  \
217 if ((err = call) < 0)           \
218   goto error;                   \
219 } G_STMT_END;
220
221 static int
222 set_hwparams (GstAlsaSrc * alsa)
223 {
224   guint rrate;
225   gint err, dir;
226   snd_pcm_hw_params_t *params;
227
228   snd_pcm_hw_params_alloca (&params);
229
230   /* choose all parameters */
231   CHECK (snd_pcm_hw_params_any (alsa->handle, params), no_config);
232   /* set the interleaved read/write format */
233   CHECK (snd_pcm_hw_params_set_access (alsa->handle, params, alsa->access),
234       wrong_access);
235   /* set the sample format */
236   CHECK (snd_pcm_hw_params_set_format (alsa->handle, params, alsa->format),
237       no_sample_format);
238   /* set the count of channels */
239   CHECK (snd_pcm_hw_params_set_channels (alsa->handle, params, alsa->channels),
240       no_channels);
241   /* set the stream rate */
242   rrate = alsa->rate;
243   CHECK (snd_pcm_hw_params_set_rate_near (alsa->handle, params, &rrate, 0),
244       no_rate);
245   if (rrate != alsa->rate)
246     goto rate_match;
247
248   if (alsa->buffer_time != -1) {
249     /* set the buffer time */
250     CHECK (snd_pcm_hw_params_set_buffer_time_near (alsa->handle, params,
251             &alsa->buffer_time, &dir), buffer_time);
252   }
253   if (alsa->period_time != -1) {
254     /* set the period time */
255     CHECK (snd_pcm_hw_params_set_period_time_near (alsa->handle, params,
256             &alsa->period_time, &dir), period_time);
257   }
258
259   /* write the parameters to device */
260   CHECK (snd_pcm_hw_params (alsa->handle, params), set_hw_params);
261
262   CHECK (snd_pcm_hw_params_get_buffer_size (params, &alsa->buffer_size),
263       buffer_size);
264
265   CHECK (snd_pcm_hw_params_get_period_size (params, &alsa->period_size, &dir),
266       period_size);
267
268   return 0;
269
270   /* ERRORS */
271 no_config:
272   {
273     GST_ELEMENT_ERROR (alsa, RESOURCE, OPEN_READ,
274         ("Broken configuration for recording: no configurations available: %s",
275             snd_strerror (err)), (NULL));
276     return err;
277   }
278 wrong_access:
279   {
280     GST_ELEMENT_ERROR (alsa, RESOURCE, OPEN_READ,
281         ("Access type not available for recording: %s", snd_strerror (err)),
282         (NULL));
283     return err;
284   }
285 no_sample_format:
286   {
287     GST_ELEMENT_ERROR (alsa, RESOURCE, OPEN_READ,
288         ("Sample format not available for recording: %s", snd_strerror (err)),
289         (NULL));
290     return err;
291   }
292 no_channels:
293   {
294     GST_ELEMENT_ERROR (alsa, RESOURCE, OPEN_READ,
295         ("Channels count (%i) not available for recording: %s",
296             alsa->channels, snd_strerror (err)), (NULL));
297     return err;
298   }
299 no_rate:
300   {
301     GST_ELEMENT_ERROR (alsa, RESOURCE, OPEN_READ,
302         ("Rate %iHz not available for recording: %s",
303             alsa->rate, snd_strerror (err)), (NULL));
304     return err;
305   }
306 rate_match:
307   {
308     GST_ELEMENT_ERROR (alsa, RESOURCE, OPEN_READ,
309         ("Rate doesn't match (requested %iHz, get %iHz)",
310             alsa->rate, err), (NULL));
311     return -EINVAL;
312   }
313 buffer_time:
314   {
315     GST_ELEMENT_ERROR (alsa, RESOURCE, OPEN_READ,
316         ("Unable to set buffer time %i for recording: %s",
317             alsa->buffer_time, snd_strerror (err)), (NULL));
318     return err;
319   }
320 buffer_size:
321   {
322     GST_ELEMENT_ERROR (alsa, RESOURCE, OPEN_READ,
323         ("Unable to get buffer size for recording: %s", snd_strerror (err)),
324         (NULL));
325     return err;
326   }
327 period_time:
328   {
329     GST_ELEMENT_ERROR (alsa, RESOURCE, OPEN_READ,
330         ("Unable to set period time %i for recording: %s", alsa->period_time,
331             snd_strerror (err)), (NULL));
332     return err;
333   }
334 period_size:
335   {
336     GST_ELEMENT_ERROR (alsa, RESOURCE, OPEN_READ,
337         ("Unable to get period size for recording: %s", snd_strerror (err)),
338         (NULL));
339     return err;
340   }
341 set_hw_params:
342   {
343     GST_ELEMENT_ERROR (alsa, RESOURCE, OPEN_READ,
344         ("Unable to set hw params for recording: %s", snd_strerror (err)),
345         (NULL));
346     return err;
347   }
348 }
349
350 static int
351 set_swparams (GstAlsaSrc * alsa)
352 {
353   int err;
354   snd_pcm_sw_params_t *params;
355
356   snd_pcm_sw_params_alloca (&params);
357
358   /* get the current swparams */
359   CHECK (snd_pcm_sw_params_current (alsa->handle, params), no_config);
360   /* start the transfer when the buffer is almost full: */
361   /* (buffer_size / avail_min) * avail_min */
362 #if 0
363   CHECK (snd_pcm_sw_params_set_start_threshold (alsa->handle, params,
364           (alsa->buffer_size / alsa->period_size) * alsa->period_size),
365       start_threshold);
366
367   /* allow the transfer when at least period_size samples can be processed */
368   CHECK (snd_pcm_sw_params_set_avail_min (alsa->handle, params,
369           alsa->period_size), set_avail);
370 #endif
371   /* align all transfers to 1 sample */
372   CHECK (snd_pcm_sw_params_set_xfer_align (alsa->handle, params, 1), set_align);
373
374   /* write the parameters to the recording device */
375   CHECK (snd_pcm_sw_params (alsa->handle, params), set_sw_params);
376
377   return 0;
378
379   /* ERRORS */
380 no_config:
381   {
382     GST_ELEMENT_ERROR (alsa, RESOURCE, OPEN_READ,
383         ("Unable to determine current swparams for recording: %s",
384             snd_strerror (err)), (NULL));
385     return err;
386   }
387 #if 0
388 start_threshold:
389   {
390     GST_ELEMENT_ERROR (alsa, RESOURCE, OPEN_READ,
391         ("Unable to set start threshold mode for recording: %s",
392             snd_strerror (err)), (NULL));
393     return err;
394   }
395 set_avail:
396   {
397     GST_ELEMENT_ERROR (alsa, RESOURCE, OPEN_READ,
398         ("Unable to set avail min for recording: %s", snd_strerror (err)),
399         (NULL));
400     return err;
401   }
402 #endif
403 set_align:
404   {
405     GST_ELEMENT_ERROR (alsa, RESOURCE, OPEN_READ,
406         ("Unable to set transfer align for recording: %s", snd_strerror (err)),
407         (NULL));
408     return err;
409   }
410 set_sw_params:
411   {
412     GST_ELEMENT_ERROR (alsa, RESOURCE, OPEN_READ,
413         ("Unable to set sw params for recording: %s", snd_strerror (err)),
414         (NULL));
415     return err;
416   }
417 }
418
419 static gboolean
420 alsasrc_parse_spec (GstAlsaSrc * alsa, GstRingBufferSpec * spec)
421 {
422   switch (spec->type) {
423     case GST_BUFTYPE_LINEAR:
424       alsa->format = snd_pcm_build_linear_format (spec->depth, spec->width,
425           spec->sign ? 0 : 1, spec->bigend ? 1 : 0);
426       break;
427     case GST_BUFTYPE_FLOAT:
428       switch (spec->format) {
429         case GST_FLOAT32_LE:
430           alsa->format = SND_PCM_FORMAT_FLOAT_LE;
431           break;
432         case GST_FLOAT32_BE:
433           alsa->format = SND_PCM_FORMAT_FLOAT_BE;
434           break;
435         case GST_FLOAT64_LE:
436           alsa->format = SND_PCM_FORMAT_FLOAT64_LE;
437           break;
438         case GST_FLOAT64_BE:
439           alsa->format = SND_PCM_FORMAT_FLOAT64_BE;
440           break;
441         default:
442           goto error;
443       }
444       break;
445     case GST_BUFTYPE_A_LAW:
446       alsa->format = SND_PCM_FORMAT_A_LAW;
447       break;
448     case GST_BUFTYPE_MU_LAW:
449       alsa->format = SND_PCM_FORMAT_MU_LAW;
450       break;
451     default:
452       goto error;
453
454   }
455   alsa->rate = spec->rate;
456   alsa->channels = spec->channels;
457   alsa->buffer_time = spec->buffer_time;
458   alsa->period_time = spec->latency_time;
459   alsa->access = SND_PCM_ACCESS_RW_INTERLEAVED;
460
461   return TRUE;
462
463   /* ERRORS */
464 error:
465   {
466     return FALSE;
467   }
468 }
469
470 static gboolean
471 gst_alsasrc_open (GstAudioSrc * asrc)
472 {
473   GstAlsaSrc *alsa;
474   gint err;
475
476   alsa = GST_ALSA_SRC (asrc);
477
478   CHECK (snd_pcm_open (&alsa->handle, alsa->device, SND_PCM_STREAM_CAPTURE,
479           SND_PCM_NONBLOCK), open_error);
480
481   if (!alsa->mixer)
482     alsa->mixer = gst_alsa_mixer_new (alsa->device, GST_ALSA_MIXER_CAPTURE);
483
484   return TRUE;
485
486   /* ERRORS */
487 open_error:
488   {
489     GST_ELEMENT_ERROR (alsa, RESOURCE, OPEN_READ,
490         ("Capture open error: %s", snd_strerror (err)), (NULL));
491     return FALSE;
492   }
493 }
494
495 static gboolean
496 gst_alsasrc_prepare (GstAudioSrc * asrc, GstRingBufferSpec * spec)
497 {
498   GstAlsaSrc *alsa;
499   gint err;
500
501   alsa = GST_ALSA_SRC (asrc);
502
503   if (!alsasrc_parse_spec (alsa, spec))
504     goto spec_parse;
505
506   CHECK (snd_pcm_nonblock (alsa->handle, 0), non_block);
507
508   CHECK (set_hwparams (alsa), hw_params_failed);
509   CHECK (set_swparams (alsa), sw_params_failed);
510   CHECK (snd_pcm_prepare (alsa->handle), prepare_failed);
511
512   alsa->bytes_per_sample = spec->bytes_per_sample;
513   spec->segsize = alsa->period_size * spec->bytes_per_sample;
514   spec->segtotal = alsa->buffer_size / alsa->period_size;
515   spec->silence_sample[0] = 0;
516   spec->silence_sample[1] = 0;
517   spec->silence_sample[2] = 0;
518   spec->silence_sample[3] = 0;
519
520   return TRUE;
521
522   /* ERRORS */
523 spec_parse:
524   {
525     GST_ELEMENT_ERROR (alsa, RESOURCE, OPEN_READ,
526         ("Error parsing spec"), (NULL));
527     return FALSE;
528   }
529 non_block:
530   {
531     GST_ELEMENT_ERROR (alsa, RESOURCE, OPEN_READ,
532         ("Could not set device to blocking: %s", snd_strerror (err)), (NULL));
533     return FALSE;
534   }
535 hw_params_failed:
536   {
537     GST_ELEMENT_ERROR (alsa, RESOURCE, OPEN_READ,
538         ("Setting of hwparams failed: %s", snd_strerror (err)), (NULL));
539     return FALSE;
540   }
541 sw_params_failed:
542   {
543     GST_ELEMENT_ERROR (alsa, RESOURCE, OPEN_READ,
544         ("Setting of swparams failed: %s", snd_strerror (err)), (NULL));
545     return FALSE;
546   }
547 prepare_failed:
548   {
549     GST_ELEMENT_ERROR (alsa, RESOURCE, OPEN_READ,
550         ("Prepare failed: %s", snd_strerror (err)), (NULL));
551     return FALSE;
552   }
553 }
554
555 static gboolean
556 gst_alsasrc_unprepare (GstAudioSrc * asrc)
557 {
558   GstAlsaSrc *alsa;
559   gint err;
560
561   alsa = GST_ALSA_SRC (asrc);
562
563   CHECK (snd_pcm_drop (alsa->handle), drop);
564
565   CHECK (snd_pcm_hw_free (alsa->handle), hw_free);
566
567   CHECK (snd_pcm_nonblock (alsa->handle, 1), non_block);
568
569   return TRUE;
570
571   /* ERRORS */
572 drop:
573   {
574     GST_ELEMENT_ERROR (alsa, RESOURCE, OPEN_READ,
575         ("Could not drop samples: %s", snd_strerror (err)), (NULL));
576     return FALSE;
577   }
578 hw_free:
579   {
580     GST_ELEMENT_ERROR (alsa, RESOURCE, OPEN_READ,
581         ("Could not free hw params: %s", snd_strerror (err)), (NULL));
582     return FALSE;
583   }
584 non_block:
585   {
586     GST_ELEMENT_ERROR (alsa, RESOURCE, OPEN_READ,
587         ("Could not set device to nonblocking: %s", snd_strerror (err)),
588         (NULL));
589     return FALSE;
590   }
591 }
592
593 static gboolean
594 gst_alsasrc_close (GstAudioSrc * asrc)
595 {
596   GstAlsaSrc *alsa = GST_ALSA_SRC (asrc);
597
598   snd_pcm_close (alsa->handle);
599
600   if (alsa->mixer) {
601     gst_alsa_mixer_free (alsa->mixer);
602     alsa->mixer = NULL;
603   }
604
605   return TRUE;
606 }
607
608 /*
609  *   Underrun and suspend recovery
610  */
611 static gint
612 xrun_recovery (snd_pcm_t * handle, gint err)
613 {
614   GST_DEBUG ("xrun recovery %d", err);
615
616   if (err == -EPIPE) {          /* under-run */
617     err = snd_pcm_prepare (handle);
618     if (err < 0)
619       GST_WARNING ("Can't recovery from underrun, prepare failed: %s",
620           snd_strerror (err));
621     return 0;
622   } else if (err == -ESTRPIPE) {
623     while ((err = snd_pcm_resume (handle)) == -EAGAIN)
624       g_usleep (100);           /* wait until the suspend flag is released */
625
626     if (err < 0) {
627       err = snd_pcm_prepare (handle);
628       if (err < 0)
629         GST_WARNING ("Can't recovery from suspend, prepare failed: %s",
630             snd_strerror (err));
631     }
632     return 0;
633   }
634   return err;
635 }
636
637 static guint
638 gst_alsasrc_read (GstAudioSrc * asrc, gpointer data, guint length)
639 {
640   GstAlsaSrc *alsa;
641   gint err;
642   gint cptr;
643   gint16 *ptr;
644
645   alsa = GST_ALSA_SRC (asrc);
646
647   cptr = length / alsa->bytes_per_sample;
648   ptr = data;
649
650   while (cptr > 0) {
651     if ((err = snd_pcm_readi (alsa->handle, ptr, cptr)) < 0) {
652       if (err == -EAGAIN) {
653         GST_DEBUG ("Read error: %s", snd_strerror (err));
654         continue;
655       } else if (xrun_recovery (alsa->handle, err) < 0) {
656         goto read_error;
657       }
658       continue;
659     }
660
661     ptr += err * alsa->channels;
662     cptr -= err;
663   }
664   return length - cptr;
665
666 read_error:
667   {
668     return length;              /* skip one period */
669   }
670 }
671
672 static guint
673 gst_alsasrc_delay (GstAudioSrc * asrc)
674 {
675   GstAlsaSrc *alsa;
676   snd_pcm_sframes_t delay;
677
678   alsa = GST_ALSA_SRC (asrc);
679
680   snd_pcm_delay (alsa->handle, &delay);
681
682   return delay;
683 }
684
685 static void
686 gst_alsasrc_reset (GstAudioSrc * asrc)
687 {
688
689 #if 0
690   GstAlsaSrc *alsa;
691   gint err;
692
693   alsa = GST_ALSA_SRC (asrc);
694
695   CHECK (snd_pcm_drop (alsa->handle), drop_error);
696   CHECK (snd_pcm_prepare (alsa->handle), prepare_error);
697
698   return;
699
700   /* ERRORS */
701 drop_error:
702   {
703     GST_ELEMENT_ERROR (alsa, RESOURCE, OPEN_READ,
704         ("alsa-reset: pcm drop error: %s", snd_strerror (err)), (NULL));
705     return;
706   }
707 prepare_error:
708   {
709     GST_ELEMENT_ERROR (alsa, RESOURCE, OPEN_READ,
710         ("alsa-reset: pcm prepare error: %s", snd_strerror (err)), (NULL));
711     return;
712   }
713 #endif
714 }