Subversion Repositories svnkaklik

Rev

Rev 654 | Details | Compare with Previous | Last modification | View Log

Rev Author Line No. Line
654 kaklik 1
	#include <stdio.h>
2
	#include <stdlib.h>
3
	#include <errno.h>
4
	#include <poll.h>
662 kaklik 5
	#include <alsa/asoundlib.h>
654 kaklik 6
 
7
	snd_pcm_t *playback_handle;
8
	short buf[4096];
9
 
10
	int
11
	playback_callback (snd_pcm_sframes_t nframes)
12
	{
13
		int err;
14
 
15
		printf ("playback callback called with %u frames\n", nframes);
16
 
17
		/* ... fill buf with data ... */
18
 
19
		if ((err = snd_pcm_writei (playback_handle, buf, nframes)) < 0) {
20
			fprintf (stderr, "write failed (%s)\n", snd_strerror (err));
21
		}
22
 
23
		return err;
24
	}
25
 
26
	main (int argc, char *argv[])
27
	{
28
 
29
		snd_pcm_hw_params_t *hw_params;
30
		snd_pcm_sw_params_t *sw_params;
31
		snd_pcm_sframes_t frames_to_deliver;
32
		int nfds;
33
		int err;
34
		struct pollfd *pfds;
35
 
36
		if ((err = snd_pcm_open (&playback_handle, argv[1], SND_PCM_STREAM_PLAYBACK, 0)) < 0) {
37
			fprintf (stderr, "cannot open audio device %s (%s)\n", 
38
				 argv[1],
39
				 snd_strerror (err));
40
			exit (1);
41
		}
42
 
43
		if ((err = snd_pcm_hw_params_malloc (&hw_params)) < 0) {
44
			fprintf (stderr, "cannot allocate hardware parameter structure (%s)\n",
45
				 snd_strerror (err));
46
			exit (1);
47
		}
48
 
49
		if ((err = snd_pcm_hw_params_any (playback_handle, hw_params)) < 0) {
50
			fprintf (stderr, "cannot initialize hardware parameter structure (%s)\n",
51
				 snd_strerror (err));
52
			exit (1);
53
		}
54
 
55
		if ((err = snd_pcm_hw_params_set_access (playback_handle, hw_params, SND_PCM_ACCESS_RW_INTERLEAVED)) < 0) {
56
			fprintf (stderr, "cannot set access type (%s)\n",
57
				 snd_strerror (err));
58
			exit (1);
59
		}
60
 
61
		if ((err = snd_pcm_hw_params_set_format (playback_handle, hw_params, SND_PCM_FORMAT_S16_LE)) < 0) {
62
			fprintf (stderr, "cannot set sample format (%s)\n",
63
				 snd_strerror (err));
64
			exit (1);
65
		}
66
 
67
		if ((err = snd_pcm_hw_params_set_rate_near (playback_handle, hw_params, 44100, 0)) < 0) {
68
			fprintf (stderr, "cannot set sample rate (%s)\n",
69
				 snd_strerror (err));
70
			exit (1);
71
		}
72
 
73
		if ((err = snd_pcm_hw_params_set_channels (playback_handle, hw_params, 2)) < 0) {
74
			fprintf (stderr, "cannot set channel count (%s)\n",
75
				 snd_strerror (err));
76
			exit (1);
77
		}
78
 
79
		if ((err = snd_pcm_hw_params (playback_handle, hw_params)) < 0) {
80
			fprintf (stderr, "cannot set parameters (%s)\n",
81
				 snd_strerror (err));
82
			exit (1);
83
		}
84
 
85
		snd_pcm_hw_params_free (hw_params);
86
 
87
		/* tell ALSA to wake us up whenever 4096 or more frames
88
		   of playback data can be delivered. Also, tell
89
		   ALSA that we'll start the device ourselves.
90
		*/
91
 
92
		if ((err = snd_pcm_sw_params_malloc (&sw_params)) < 0) {
93
			fprintf (stderr, "cannot allocate software parameters structure (%s)\n",
94
				 snd_strerror (err));
95
			exit (1);
96
		}
97
		if ((err = snd_pcm_sw_params_current (playback_handle, sw_params)) < 0) {
98
			fprintf (stderr, "cannot initialize software parameters structure (%s)\n",
99
				 snd_strerror (err));
100
			exit (1);
101
		}
102
		if ((err = snd_pcm_sw_params_set_avail_min (playback_handle, sw_params, 4096)) < 0) {
103
			fprintf (stderr, "cannot set minimum available count (%s)\n",
104
				 snd_strerror (err));
105
			exit (1);
106
		}
107
		if ((err = snd_pcm_sw_params_set_start_threshold (playback_handle, sw_params, 0U)) < 0) {
108
			fprintf (stderr, "cannot set start mode (%s)\n",
109
				 snd_strerror (err));
110
			exit (1);
111
		}
112
		if ((err = snd_pcm_sw_params (playback_handle, sw_params)) < 0) {
113
			fprintf (stderr, "cannot set software parameters (%s)\n",
114
				 snd_strerror (err));
115
			exit (1);
116
		}
117
 
118
		/* the interface will interrupt the kernel every 4096 frames, and ALSA
119
		   will wake up this program very soon after that.
120
		*/
121
 
122
		if ((err = snd_pcm_prepare (playback_handle)) < 0) {
123
			fprintf (stderr, "cannot prepare audio interface for use (%s)\n",
124
				 snd_strerror (err));
125
			exit (1);
126
		}
127
 
128
		while (1) {
129
 
130
			/* wait till the interface is ready for data, or 1 second
131
			   has elapsed.
132
			*/
133
 
134
			if ((err = snd_pcm_wait (playback_handle, 1000)) < 0) {
135
			        fprintf (stderr, "poll failed (%s)\n", strerror (errno));
136
			        break;
137
			}	           
138
 
139
			/* find out how much space is available for playback data */
140
 
141
			if ((frames_to_deliver = snd_pcm_avail_update (playback_handle)) < 0) {
142
				if (frames_to_deliver == -EPIPE) {
143
					fprintf (stderr, "an xrun occured\n");
144
					break;
145
				} else {
146
					fprintf (stderr, "unknown ALSA avail update return value (%d)\n", 
147
						 frames_to_deliver);
148
					break;
149
				}
150
			}
151
 
152
			frames_to_deliver = frames_to_deliver > 4096 ? 4096 : frames_to_deliver;
153
 
154
			/* deliver the data */
155
 
156
			if (playback_callback (frames_to_deliver) != frames_to_deliver) {
157
			        fprintf (stderr, "playback callback failed\n");
158
				break;
159
			}
160
		}
161
 
162
		snd_pcm_close (playback_handle);
163
		exit (0);
164
	}
165