xref: /OK3568_Linux_fs/buildroot/package/madplay/0001-switch-to-new-alsa-api.patch (revision 4882a59341e53eb6f0b4789bf948001014eff981)
1*4882a593SmuzhiyunSwitch madplay to the new API. This is done thanks to a patch written
2*4882a593Smuzhiyunby Micha Nelissen <micha@neli.hopto.org> and available at
3*4882a593Smuzhiyunhttp://article.gmane.org/gmane.comp.audio.mad.devel/729.
4*4882a593Smuzhiyun
5*4882a593Smuzhiyun--- madplay-0.15.2b/audio_alsa.c	2008-10-18 15:10:16.000000000 +0200
6*4882a593Smuzhiyun+++ madplay-0.15.2b/audio_alsa.c.new	2008-10-18 15:03:27.000000000 +0200
7*4882a593Smuzhiyun@@ -28,31 +28,30 @@
8*4882a593Smuzhiyun
9*4882a593Smuzhiyun #include <errno.h>
10*4882a593Smuzhiyun
11*4882a593Smuzhiyun-#define ALSA_PCM_OLD_HW_PARAMS_API
12*4882a593Smuzhiyun-#define ALSA_PCM_OLD_SW_PARAMS_API
13*4882a593Smuzhiyun #include <alsa/asoundlib.h>
14*4882a593Smuzhiyun
15*4882a593Smuzhiyun #include <mad.h>
16*4882a593Smuzhiyun
17*4882a593Smuzhiyun #include "audio.h"
18*4882a593Smuzhiyun
19*4882a593Smuzhiyun-char *buf	= NULL;
20*4882a593Smuzhiyun-int paused	= 0;
21*4882a593Smuzhiyun+#define BUFFER_TIME_MAX     500000
22*4882a593Smuzhiyun
23*4882a593Smuzhiyun-int rate	= -1;
24*4882a593Smuzhiyun-int channels	= -1;
25*4882a593Smuzhiyun-int bitdepth	= -1;
26*4882a593Smuzhiyun-int sample_size	= -1;
27*4882a593Smuzhiyun-
28*4882a593Smuzhiyun-int buffer_time		= 500000;
29*4882a593Smuzhiyun-int period_time		= 100000;
30*4882a593Smuzhiyun-char *defaultdev	= "plughw:0,0";
31*4882a593Smuzhiyun+unsigned char *buf  = NULL;
32*4882a593Smuzhiyun+int paused	    = 0;
33*4882a593Smuzhiyun+
34*4882a593Smuzhiyun+unsigned int rate           = 0;
35*4882a593Smuzhiyun+unsigned int channels	    = -1;
36*4882a593Smuzhiyun+unsigned int bitdepth	    = -1;
37*4882a593Smuzhiyun+unsigned int sample_size    = -1;
38*4882a593Smuzhiyun+
39*4882a593Smuzhiyun+unsigned int buffer_time;
40*4882a593Smuzhiyun+unsigned int period_time;
41*4882a593Smuzhiyun+char *defaultdev	    = "plughw:0,0";
42*4882a593Smuzhiyun
43*4882a593Smuzhiyun snd_pcm_hw_params_t *alsa_hwparams;
44*4882a593Smuzhiyun snd_pcm_sw_params_t *alsa_swparams;
45*4882a593Smuzhiyun
46*4882a593Smuzhiyun-snd_pcm_sframes_t buffer_size;
47*4882a593Smuzhiyun-snd_pcm_sframes_t period_size;
48*4882a593Smuzhiyun+snd_pcm_uframes_t buffer_size;
49*4882a593Smuzhiyun
50*4882a593Smuzhiyun snd_pcm_format_t  alsa_format = -1;
51*4882a593Smuzhiyun snd_pcm_access_t  alsa_access = SND_PCM_ACCESS_MMAP_INTERLEAVED;
52*4882a593Smuzhiyun@@ -66,14 +65,20 @@
53*4882a593Smuzhiyun 		 snd_pcm_hw_params_t *params,
54*4882a593Smuzhiyun 		 snd_pcm_access_t access)
55*4882a593Smuzhiyun {
56*4882a593Smuzhiyun-	int err, dir;
57*4882a593Smuzhiyun-
58*4882a593Smuzhiyun+	int err;
59*4882a593Smuzhiyun+
60*4882a593Smuzhiyun 	/* choose all parameters */
61*4882a593Smuzhiyun 	err = snd_pcm_hw_params_any(handle,params);
62*4882a593Smuzhiyun 	if (err < 0) {
63*4882a593Smuzhiyun 		printf("Access type not available for playback: %s\n", snd_strerror(err));
64*4882a593Smuzhiyun 		return err;
65*4882a593Smuzhiyun 	}
66*4882a593Smuzhiyun+	/* set the access type */
67*4882a593Smuzhiyun+	err = snd_pcm_hw_params_set_access(handle, params, alsa_access);
68*4882a593Smuzhiyun+	if (err < 0) {
69*4882a593Smuzhiyun+		printf("Sample format not available for playback: %s\n", snd_strerror(err));
70*4882a593Smuzhiyun+		return err;
71*4882a593Smuzhiyun+	}
72*4882a593Smuzhiyun 	/* set the sample format */
73*4882a593Smuzhiyun 	err = snd_pcm_hw_params_set_format(handle, params, alsa_format);
74*4882a593Smuzhiyun 	if (err < 0) {
75*4882a593Smuzhiyun@@ -87,29 +92,38 @@
76*4882a593Smuzhiyun 		return err;
77*4882a593Smuzhiyun 	}
78*4882a593Smuzhiyun 	/* set the stream rate */
79*4882a593Smuzhiyun-	err = snd_pcm_hw_params_set_rate_near(handle, params, rate, 0);
80*4882a593Smuzhiyun+	err = snd_pcm_hw_params_set_rate(handle, params, rate, 0);
81*4882a593Smuzhiyun 	if (err < 0) {
82*4882a593Smuzhiyun 		printf("Rate %iHz not available for playback: %s\n", rate, snd_strerror(err));
83*4882a593Smuzhiyun 		return err;
84*4882a593Smuzhiyun 	}
85*4882a593Smuzhiyun-	if (err != rate) {
86*4882a593Smuzhiyun-		printf("Rate doesn't match (requested %iHz, get %iHz)\n", rate, err);
87*4882a593Smuzhiyun-		return -EINVAL;
88*4882a593Smuzhiyun-	}
89*4882a593Smuzhiyun+	err = snd_pcm_hw_params_get_buffer_time_max(params, &buffer_time, NULL);
90*4882a593Smuzhiyun+        if (err < 0) {
91*4882a593Smuzhiyun+                printf("Unable to retrieve buffer time: %s\n", snd_strerror(err));
92*4882a593Smuzhiyun+                return err;
93*4882a593Smuzhiyun+        }
94*4882a593Smuzhiyun+        if (buffer_time > BUFFER_TIME_MAX)
95*4882a593Smuzhiyun+                buffer_time = BUFFER_TIME_MAX;
96*4882a593Smuzhiyun 	/* set buffer time */
97*4882a593Smuzhiyun-	err = snd_pcm_hw_params_set_buffer_time_near(handle, params, buffer_time, &dir);
98*4882a593Smuzhiyun+	err = snd_pcm_hw_params_set_buffer_time_near(handle, params, &buffer_time, 0);
99*4882a593Smuzhiyun 	if (err < 0) {
100*4882a593Smuzhiyun 		printf("Unable to set buffer time %i for playback: %s\n", buffer_time, snd_strerror(err));
101*4882a593Smuzhiyun 		return err;
102*4882a593Smuzhiyun 	}
103*4882a593Smuzhiyun-	buffer_size = snd_pcm_hw_params_get_buffer_size(params);
104*4882a593Smuzhiyun+        if (period_time * 4 > buffer_time)
105*4882a593Smuzhiyun+                period_time = buffer_time / 4;
106*4882a593Smuzhiyun 	/* set period time */
107*4882a593Smuzhiyun-	err = snd_pcm_hw_params_set_period_time_near(handle, params, period_time, &dir);
108*4882a593Smuzhiyun+	err = snd_pcm_hw_params_set_period_time_near(handle, params, &period_time, NULL);
109*4882a593Smuzhiyun 	if (err < 0) {
110*4882a593Smuzhiyun 		printf("Unable to set period time %i for playback: %s\n", period_time, snd_strerror(err));
111*4882a593Smuzhiyun 		return err;
112*4882a593Smuzhiyun 	}
113*4882a593Smuzhiyun-	period_size = snd_pcm_hw_params_get_period_size(params, &dir);
114*4882a593Smuzhiyun+        /* retrieve buffer size */
115*4882a593Smuzhiyun+	err = snd_pcm_hw_params_get_buffer_size(params, &buffer_size);
116*4882a593Smuzhiyun+        if (err < 0) {
117*4882a593Smuzhiyun+                printf("Unable to retrieve buffer size: %s\n", snd_strerror(err));
118*4882a593Smuzhiyun+                return err;
119*4882a593Smuzhiyun+        }
120*4882a593Smuzhiyun 	/* write the parameters to device */
121*4882a593Smuzhiyun 	err = snd_pcm_hw_params(handle, params);
122*4882a593Smuzhiyun 	if (err < 0) {
123*4882a593Smuzhiyun@@ -123,6 +137,7 @@
124*4882a593Smuzhiyun int set_swparams(snd_pcm_t *handle,
125*4882a593Smuzhiyun 		 snd_pcm_sw_params_t *params)
126*4882a593Smuzhiyun {
127*4882a593Smuzhiyun+        unsigned int start_threshold;
128*4882a593Smuzhiyun 	int err;
129*4882a593Smuzhiyun
130*4882a593Smuzhiyun         /* get current swparams */
131*4882a593Smuzhiyun@@ -136,13 +151,7 @@
132*4882a593Smuzhiyun         if (err < 0) {
133*4882a593Smuzhiyun                 printf("Unable to set start threshold mode for playback: %s\n", snd_strerror(err));
134*4882a593Smuzhiyun                 return err;
135*4882a593Smuzhiyun-										        }
136*4882a593Smuzhiyun-        /* allow transfer when at least period_size samples can be processed */
137*4882a593Smuzhiyun-        err = snd_pcm_sw_params_set_avail_min(handle, params, period_size);
138*4882a593Smuzhiyun-        if (err < 0) {
139*4882a593Smuzhiyun-                printf("Unable to set avail min for playback: %s\n", snd_strerror(err));
140*4882a593Smuzhiyun-                return err;
141*4882a593Smuzhiyun-												        }
142*4882a593Smuzhiyun+	}
143*4882a593Smuzhiyun         /* align all transfers to 1 samples */
144*4882a593Smuzhiyun         err = snd_pcm_sw_params_set_xfer_align(handle, params, 1);
145*4882a593Smuzhiyun         if (err < 0) {
146*4882a593Smuzhiyun@@ -190,7 +199,7 @@
147*4882a593Smuzhiyun 	rate		= config->speed;
148*4882a593Smuzhiyun
149*4882a593Smuzhiyun 	if ( bitdepth == 0 )
150*4882a593Smuzhiyun-		config->precision = bitdepth = 32;
151*4882a593Smuzhiyun+		config->precision = bitdepth = 16;
152*4882a593Smuzhiyun
153*4882a593Smuzhiyun 	switch (bitdepth)
154*4882a593Smuzhiyun 	{
155*4882a593Smuzhiyun@@ -241,7 +250,7 @@
156*4882a593Smuzhiyun 		return -1;
157*4882a593Smuzhiyun 	}
158*4882a593Smuzhiyun
159*4882a593Smuzhiyun-	buf = malloc(buffer_size);
160*4882a593Smuzhiyun+	buf = malloc(buffer_size * sample_size);
161*4882a593Smuzhiyun 	if (buf == NULL) {
162*4882a593Smuzhiyun 		audio_error="unable to allocate output buffer table";
163*4882a593Smuzhiyun 		return -1;
164*4882a593Smuzhiyun@@ -279,7 +288,7 @@
165*4882a593Smuzhiyun int play(struct audio_play *play)
166*4882a593Smuzhiyun {
167*4882a593Smuzhiyun 	int err, len;
168*4882a593Smuzhiyun-	char *ptr;
169*4882a593Smuzhiyun+	unsigned char *ptr;
170*4882a593Smuzhiyun
171*4882a593Smuzhiyun 	ptr = buf;
172*4882a593Smuzhiyun 	len = play->nsamples;
173*4882a593Smuzhiyun
174