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

File pulse-audio-alsa-threaded.c, 4.8 KB (added by jstedfast, 4 years 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
21snd_pcm_t *pcm = NULL;
22
23bool 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   
127cleanup:
128    snd_pcm_hw_params_free (params);
129   
130    return result;
131}
132
133void *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
170int 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}