0001-switch-to-new-alsa-api.patch 5.13 KB
Switch madplay to the new API. This is done thanks to a patch written
by Micha Nelissen <micha@neli.hopto.org> and available at
http://article.gmane.org/gmane.comp.audio.mad.devel/729.

--- madplay-0.15.2b/audio_alsa.c	2008-10-18 15:10:16.000000000 +0200
+++ madplay-0.15.2b/audio_alsa.c.new	2008-10-18 15:03:27.000000000 +0200
@@ -28,31 +28,30 @@

 #include <errno.h>

-#define ALSA_PCM_OLD_HW_PARAMS_API
-#define ALSA_PCM_OLD_SW_PARAMS_API
 #include <alsa/asoundlib.h>

 #include <mad.h>

 #include "audio.h"

-char *buf	= NULL;
-int paused	= 0;
+#define BUFFER_TIME_MAX     500000

-int rate	= -1;
-int channels	= -1;
-int bitdepth	= -1;
-int sample_size	= -1;
-
-int buffer_time		= 500000;
-int period_time		= 100000;
-char *defaultdev	= "plughw:0,0";
+unsigned char *buf  = NULL;
+int paused	    = 0;
+
+unsigned int rate           = 0;
+unsigned int channels	    = -1;
+unsigned int bitdepth	    = -1;
+unsigned int sample_size    = -1;
+
+unsigned int buffer_time;
+unsigned int period_time;
+char *defaultdev	    = "plughw:0,0";

 snd_pcm_hw_params_t *alsa_hwparams;
 snd_pcm_sw_params_t *alsa_swparams;

-snd_pcm_sframes_t buffer_size;
-snd_pcm_sframes_t period_size;
+snd_pcm_uframes_t buffer_size;

 snd_pcm_format_t  alsa_format = -1;
 snd_pcm_access_t  alsa_access = SND_PCM_ACCESS_MMAP_INTERLEAVED;
@@ -66,14 +65,20 @@
 		 snd_pcm_hw_params_t *params,
 		 snd_pcm_access_t access)
 {
-	int err, dir;
-	
+	int err;
+
 	/* choose all parameters */
 	err = snd_pcm_hw_params_any(handle,params);
 	if (err < 0) {
 		printf("Access type not available for playback: %s\n", snd_strerror(err));
 		return err;
 	}
+	/* set the access type */
+	err = snd_pcm_hw_params_set_access(handle, params, alsa_access);
+	if (err < 0) {
+		printf("Sample format not available for playback: %s\n", snd_strerror(err));
+		return err;
+	}
 	/* set the sample format */
 	err = snd_pcm_hw_params_set_format(handle, params, alsa_format);
 	if (err < 0) {
@@ -87,29 +92,38 @@
 		return err;
 	}
 	/* set the stream rate */
-	err = snd_pcm_hw_params_set_rate_near(handle, params, rate, 0);
+	err = snd_pcm_hw_params_set_rate(handle, params, rate, 0);
 	if (err < 0) {
 		printf("Rate %iHz not available for playback: %s\n", rate, snd_strerror(err));
 		return err;
 	}
-	if (err != rate) {
-		printf("Rate doesn't match (requested %iHz, get %iHz)\n", rate, err);
-		return -EINVAL;
-	}
+	err = snd_pcm_hw_params_get_buffer_time_max(params, &buffer_time, NULL);
+        if (err < 0) {
+                printf("Unable to retrieve buffer time: %s\n", snd_strerror(err));
+                return err;
+        }
+        if (buffer_time > BUFFER_TIME_MAX)
+                buffer_time = BUFFER_TIME_MAX;
 	/* set buffer time */
-	err = snd_pcm_hw_params_set_buffer_time_near(handle, params, buffer_time, &dir);
+	err = snd_pcm_hw_params_set_buffer_time_near(handle, params, &buffer_time, 0);
 	if (err < 0) {
 		printf("Unable to set buffer time %i for playback: %s\n", buffer_time, snd_strerror(err));
 		return err;
 	}
-	buffer_size = snd_pcm_hw_params_get_buffer_size(params);
+        if (period_time * 4 > buffer_time)
+                period_time = buffer_time / 4;
 	/* set period time */
-	err = snd_pcm_hw_params_set_period_time_near(handle, params, period_time, &dir);
+	err = snd_pcm_hw_params_set_period_time_near(handle, params, &period_time, NULL);
 	if (err < 0) {
 		printf("Unable to set period time %i for playback: %s\n", period_time, snd_strerror(err));
 		return err;
 	}
-	period_size = snd_pcm_hw_params_get_period_size(params, &dir);
+        /* retrieve buffer size */
+	err = snd_pcm_hw_params_get_buffer_size(params, &buffer_size);
+        if (err < 0) {
+                printf("Unable to retrieve buffer size: %s\n", snd_strerror(err));
+                return err;
+        }
 	/* write the parameters to device */
 	err = snd_pcm_hw_params(handle, params);
 	if (err < 0) {
@@ -123,6 +137,7 @@
 int set_swparams(snd_pcm_t *handle,
 		 snd_pcm_sw_params_t *params)
 {
+        unsigned int start_threshold;
 	int err;

         /* get current swparams */
@@ -136,13 +151,7 @@
         if (err < 0) {
                 printf("Unable to set start threshold mode for playback: %s\n", snd_strerror(err));
                 return err;
-										        }
-        /* allow transfer when at least period_size samples can be processed */
-        err = snd_pcm_sw_params_set_avail_min(handle, params, period_size);
-        if (err < 0) {
-                printf("Unable to set avail min for playback: %s\n", snd_strerror(err));
-                return err;
-												        }
+	}
         /* align all transfers to 1 samples */
         err = snd_pcm_sw_params_set_xfer_align(handle, params, 1);
         if (err < 0) {
@@ -190,7 +199,7 @@
 	rate		= config->speed;

 	if ( bitdepth == 0 )
-		config->precision = bitdepth = 32;
+		config->precision = bitdepth = 16;

 	switch (bitdepth)
 	{
@@ -241,7 +250,7 @@
 		return -1;
 	}

-	buf = malloc(buffer_size);
+	buf = malloc(buffer_size * sample_size);
 	if (buf == NULL) {
 		audio_error="unable to allocate output buffer table";
 		return -1;
@@ -279,7 +288,7 @@
 int play(struct audio_play *play)
 {
 	int err, len;
-	char *ptr;
+	unsigned char *ptr;

 	ptr = buf;
 	len = play->nsamples;