[xiph-commits] r9570 - trunk/ao/src/plugins/alsa09

j at svn.xiph.org j at svn.xiph.org
Sat Jul 16 12:14:39 PDT 2005


Author: j
Date: 2005-07-16 12:14:37 -0700 (Sat, 16 Jul 2005)
New Revision: 9570

Modified:
   trunk/ao/src/plugins/alsa09/ao_alsa09.c
Log:
- change AO_ALSA_PERIOD_TIME back to 0 so its calculated by default.
- apply patch from clemens (at) ladisch.de (fixes:612)

The attached patch makes various enhancements to libao's ALSA plugin:

* it isn't necessary to use a separate snd_pcm_access_mask_t variable to set the access mask;

* add a sample rate check (similar to the OSS plugin);

* return the correct error code when calling snd_pcm_prepare() after an underrun;

* set the start_threshold to a positive value ?\226?\128?\147 using zero can result in an immediate underrun when the first write is very small;

* various comments were wrong or misleading.




Modified: trunk/ao/src/plugins/alsa09/ao_alsa09.c
===================================================================
--- trunk/ao/src/plugins/alsa09/ao_alsa09.c	2005-07-16 05:18:52 UTC (rev 9569)
+++ trunk/ao/src/plugins/alsa09/ao_alsa09.c	2005-07-16 19:14:37 UTC (rev 9570)
@@ -42,9 +42,8 @@
 /* default 500 millisecond buffer */
 #define AO_ALSA_BUFFER_TIME 500000
 
-/* the period time is calculated if not given as an option
- * note, playback starts after four of these are in the buffer */
-#define AO_ALSA_PERIOD_TIME 50
+/* the period time is calculated if not given as an option */
+#define AO_ALSA_PERIOD_TIME 0
 
 /* number of samples between interrupts
  * supplying a period_time to ao overrides the use of this  */
@@ -214,29 +213,22 @@
 		ao_sample_format *format)
 {
 	snd_pcm_hw_params_t   *params;
-	snd_pcm_access_mask_t *access;
 	int err;
 	unsigned int rate = format->rate;
 
 	/* allocate the hardware parameter structure */
 	snd_pcm_hw_params_alloca(&params);
-	snd_pcm_access_mask_alloca(&access);
 
-	/* fetch the current hardware parameters */
+	/* fetch all possible hardware parameters */
 	internal->cmd = "snd_pcm_hw_params_any";
 	err = snd_pcm_hw_params_any(internal->pcm_handle, params);
 	if (err < 0)
 		return err;
 
-	/* create a null access mask */
-	snd_pcm_access_mask_none(access);
-
-	snd_pcm_access_mask_set(access, internal->access_mask);
-
-	/* commit the access value to params structure */
+	/* set the access type */
 	internal->cmd = "snd_pcm_hw_params_set_access";
-	err = snd_pcm_hw_params_set_access_mask(internal->pcm_handle,
-			params, access);
+	err = snd_pcm_hw_params_set_access(internal->pcm_handle,
+			params, internal->access_mask);
 	if (err < 0)
 		return err;
 
@@ -263,17 +255,18 @@
 			params, &rate, 0);
 	if (err < 0)
 		return err;
+	if (rate > 1.05 * format->rate || rate < 0.95 * format->rate) {
+		fprintf(stderr, "warning: sample rate %i not supported "
+			"by the hardware, using %u\n", format->rate, rate);
+	}
 
-	/* set the length of the hardware sample buffer in milliseconds */
+	/* set the length of the hardware sample buffer in microseconds */
 	internal->cmd = "snd_pcm_hw_params_set_buffer_time_near";
 	err = snd_pcm_hw_params_set_buffer_time_near(internal->pcm_handle,
 			params, &(internal->buffer_time), 0);
 	if (err < 0)
 		return err;
 
-	/* save the buffer time in case alsa overrode it */
-	/*internal->buffer_time = err;*/
-
 	/* calculate a period time of one half sample time */
 	if ((internal->period_time == 0) && (rate > 0))
 		internal->period_time =
@@ -292,14 +285,14 @@
 	if (err < 0)
 		return err;
 
-	/* save the period size in bytes for posterity */
+	/* save the period size in frames for posterity */
 	internal->cmd = "snd_pcm_hw_get_period_size";
 	err = snd_pcm_hw_params_get_period_size(params, 
 						&(internal->period_size), 0);
 	if (err < 0)
 		return err;
 
-	/* save the buffer size in bytes for posterity */
+	/* save the buffer size in frames for posterity */
 	internal->cmd = "snd_pcm_hw_get_period_size";
 	err = snd_pcm_hw_params_get_buffer_size(params, 
 						&(internal->buffer_size)); 
@@ -325,14 +318,10 @@
 	if (err < 0)
 		return err;
 
-	/* allow transfers to start when there are four periods */
-	/* setting the threshold to a very big values seems to cause a
-	   deadlock for dmix in a pol().  So here we just set it to 0,
-	   I'm not sure why we need to set a threshold > 0 anyway, maybe 
-	   someone could enlighten me. - shank */
+	/* allow transfers to start when there is one period */
 	internal->cmd = "snd_pcm_sw_params_set_start_threshold";
 	err = snd_pcm_sw_params_set_start_threshold(internal->pcm_handle,
-			params, /*internal->period_size << 2*/0);
+			params, internal->period_size);
 	if (err < 0)
 		return err;
 
@@ -419,7 +408,7 @@
 		internal->cmd = "underrun recovery: snd_pcm_prepare";
 		err = snd_pcm_prepare(internal->pcm_handle);
 		if (err < 0)
-			return -1;
+			return err;
 	} else if (err == -ESTRPIPE) {
 		/* application was suspended, wait until suspend flag clears */
 		internal->cmd = "suspend recovery: snd_pcm_prepare";



More information about the commits mailing list