Ticket #323: pulse-audio-alsa-threaded.c

File pulse-audio-alsa-threaded.c, 4.8 kB (added by jstedfast, 4 months ago)
Line 
1 #include <stdlib.h>
2
3 #include <poll.h>
4 #include <stdio.h>
5 #include <sys/types.h>
6 #include <string.h>
7 #include <unistd.h>
8 #include <fcntl.h>
9 #include <errno.h>
10 #include <pthread.h>
11 #include <asoundlib.h>
12
13 #include <stdint.h>
14 #include <limits.h>
15 #include <glib.h>
16
17 #define bool int
18 #define false 0
19 #define true 1
20
21 snd_pcm_t *pcm = NULL;
22
23 bool init_audio_bug ()
24 {   
25     bool result = false;
26     snd_pcm_hw_params_t *params = NULL;
27     uint32_t buffer_time = 500000; // request 0.5 seconds of buffer time.
28     int err = 0;
29     int dir = 0;
30     int channels = 1;
31     unsigned int rate = 44100;
32     unsigned int actual_rate = rate;
33
34     // Open a pcm device
35     result = snd_pcm_open (&pcm, "default", SND_PCM_STREAM_PLAYBACK, 0);
36     if (result != 0) {
37         fprintf (stderr, "AudioNode::Initialize (): cannot open audio device: %s\n", snd_strerror (result));
38         pcm = NULL;
39         return false;
40     }
41
42     snd_output_t *output = NULL;
43     err = snd_output_stdio_attach (&output, stdout, 0);
44     if (err < 0) {
45         fprintf(stderr, "AudioNode::SetupHW (): Could not create alsa output: %s\n", snd_strerror (err));
46     }
47
48     err = snd_pcm_hw_params_malloc (&params);
49     if (err < 0) {
50         fprintf(stderr, "AudioNode::SetupHW (): Audio HW setup failed (malloc): %s\n", snd_strerror (err));
51         return false;
52     }
53
54     // choose all parameters
55     err = snd_pcm_hw_params_any (pcm, params);
56     if (err < 0) {
57         fprintf (stderr, "AudioNode::SetupHW (): Audio HW setup failed (no configurations available): %s\n", snd_strerror (err));
58         goto cleanup;
59     }
60    
61     if (output != NULL) {
62         printf ("AudioNode::SetupHW (): hw configurations:\n");
63         snd_pcm_hw_params_dump (params, output);
64     }
65    
66     // enable software resampling
67     err = snd_pcm_hw_params_set_rate_resample (pcm, params, 1);
68     if (err < 0) {
69         fprintf (stderr, "AudioNode::SetupHW (): Audio HW setup failed (could not enable resampling): %s\n", snd_strerror (err));
70         goto cleanup;
71     }
72    
73     // set transfer mode (mmap in our case)
74     err = snd_pcm_hw_params_set_access (pcm, params, SND_PCM_ACCESS_RW_INTERLEAVED);
75     if (err < 0) {
76         fprintf (stderr, "AudioNode::SetupHW (): Audio HW setup failed (access type not available for playback): %s\n", snd_strerror(err));
77         goto cleanup;
78     }
79
80     // set audio format
81     err = snd_pcm_hw_params_set_format (pcm, params, SND_PCM_FORMAT_S16);
82     if (err < 0) {
83         fprintf (stderr, "AudioNode::SetupHW (): Audio HW setup failed (sample format not available for playback): %s\n", snd_strerror(err));
84         goto cleanup;
85     }
86    
87     // set channel count
88     err = snd_pcm_hw_params_set_channels (pcm, params, channels);
89     if (err < 0) {
90         fprintf (stderr, "AudioNode::SetupHW (): Audio HW setup failed (channels count %i not available for playback): %s\n", channels, snd_strerror (err));
91         goto cleanup;
92     }
93    
94     // set sample rate
95     err = snd_pcm_hw_params_set_rate_near (pcm, params, &actual_rate, 0);
96     if (err < 0) {
97         fprintf (stderr, "AudioNode::SetupHW (): Audio HW setup failed (sample rate %i Hz not available for playback): %s\n", rate, snd_strerror (err));
98         goto cleanup;
99     } else if (actual_rate != rate) {
100         fprintf (stderr, "AudioNode::SetupHW (): Audio HW setup failed (sample rate %i Hz not available for playback, only got %i Hz).\n", rate, actual_rate);
101         goto cleanup;
102     }
103    
104     // set the buffer time
105     err = snd_pcm_hw_params_set_buffer_time_near (pcm, params, &buffer_time, &dir);
106     if (err < 0) {
107         fprintf (stderr, "AudioNode::SetupHW (): Audio HW setup failed (unable to set buffer time %i for playback: %s\n", buffer_time, snd_strerror (err));
108         goto cleanup;
109     }
110
111     // write the parameters to device
112     err = snd_pcm_hw_params (pcm, params);
113     if (err < 0) {
114         fprintf (stderr, "AudioNode::SetupHW (): Audio HW setup failed (unable to set hw params for playback: %s)\n", snd_strerror (err));
115         goto cleanup;
116     }
117    
118     printf ("AudioNode::SetupHW (): succeeded\n");
119     if (output != NULL) {
120         snd_pcm_hw_params_dump (params, output);
121     }
122
123     printf ("AudioNode::SetupHW (): hardware pause support: %s\n", snd_pcm_hw_params_can_pause (params) == 0 ? "no" : "yes");
124
125     result = true;
126    
127 cleanup:
128     snd_pcm_hw_params_free (params);
129    
130     return result;
131 }
132
133 void *loop (void *context)
134 {
135     printf ("Started loop\n");
136
137     if (!init_audio_bug ())
138         return NULL;
139
140     int result;
141     int size = 8568;
142     void *silence = g_malloc0 (size);
143     int i;
144     snd_pcm_sframes_t delay;   
145     int fd;
146
147     fd = open ("mini.wav", O_RDONLY);
148     if (fd < 0)
149         printf ("Open failed: %s\n", strerror (errno));
150     if (read (fd, silence, 8568) <= 0)
151         printf ("Read failed: %s\n", strerror (errno));
152     snd_pcm_writei (pcm, silence, size / 2);
153     close (fd);
154
155 //  snd_pcm_delay (pcm);
156     if ((result = snd_pcm_start (pcm)) < 0) {
157         printf ("start failed: %s\n", snd_strerror (result));
158     }
159     printf ("Sleeping...\n");
160     sleep (1);
161     printf ("Slept\n");
162
163     //snd_pcm_drop (pcm);
164     snd_pcm_close (pcm);
165
166     printf ("Exited loop\n");
167 }
168
169
170 int main ()
171 {
172     pthread_t thread;
173     pthread_create (&thread, NULL, loop, NULL);
174     printf ("About to join\n");
175     pthread_join (thread, NULL);
176     printf ("Joined\n");
177     return 0;
178 }
179