bluetooth: Remove commented out code.
[profile/ivi/pulseaudio-panda.git] / src / tests / alsa-time-test.c
1 #ifndef _GNU_SOURCE
2 #define _GNU_SOURCE
3 #endif
4
5 #include <assert.h>
6 #include <inttypes.h>
7 #include <time.h>
8
9 #include <alsa/asoundlib.h>
10
11 static uint64_t timespec_us(const struct timespec *ts) {
12     return
13         ts->tv_sec * 1000000LLU +
14         ts->tv_nsec / 1000LLU;
15 }
16
17 int main(int argc, char *argv[]) {
18     const char *dev;
19     int r, cap;
20     snd_pcm_hw_params_t *hwparams;
21     snd_pcm_sw_params_t *swparams;
22     snd_pcm_status_t *status;
23     snd_pcm_t *pcm;
24     unsigned rate = 44100;
25     unsigned periods = 2;
26     snd_pcm_uframes_t boundary, buffer_size = 44100/10; /* 100s */
27     int dir = 1;
28     struct timespec start, last_timestamp = { 0, 0 };
29     uint64_t start_us;
30     snd_pcm_sframes_t last_avail = 0, last_delay = 0;
31     struct pollfd *pollfds;
32     int n_pollfd;
33     int64_t sample_count = 0;
34
35     snd_pcm_hw_params_alloca(&hwparams);
36     snd_pcm_sw_params_alloca(&swparams);
37     snd_pcm_status_alloca(&status);
38
39     r = clock_gettime(CLOCK_MONOTONIC, &start);
40     assert(r == 0);
41
42     start_us = timespec_us(&start);
43
44     dev = argc > 1 ? argv[1] : "front:AudioPCI";
45     cap = argc > 2 ? atoi(argv[2]) : 0;
46
47     if (cap == 0)
48       r = snd_pcm_open(&pcm, dev, SND_PCM_STREAM_PLAYBACK, 0);
49     else
50       r = snd_pcm_open(&pcm, dev, SND_PCM_STREAM_CAPTURE, 0);
51     assert(r == 0);
52
53     r = snd_pcm_hw_params_any(pcm, hwparams);
54     assert(r == 0);
55
56     r = snd_pcm_hw_params_set_rate_resample(pcm, hwparams, 0);
57     assert(r == 0);
58
59     r = snd_pcm_hw_params_set_access(pcm, hwparams, SND_PCM_ACCESS_RW_INTERLEAVED);
60     assert(r == 0);
61
62     r = snd_pcm_hw_params_set_format(pcm, hwparams, SND_PCM_FORMAT_S16_LE);
63     assert(r == 0);
64
65     r = snd_pcm_hw_params_set_rate_near(pcm, hwparams, &rate, NULL);
66     assert(r == 0);
67
68     r = snd_pcm_hw_params_set_channels(pcm, hwparams, 2);
69     assert(r == 0);
70
71     r = snd_pcm_hw_params_set_periods_integer(pcm, hwparams);
72     assert(r == 0);
73
74     r = snd_pcm_hw_params_set_periods_near(pcm, hwparams, &periods, &dir);
75     assert(r == 0);
76
77     r = snd_pcm_hw_params_set_buffer_size_near(pcm, hwparams, &buffer_size);
78     assert(r == 0);
79
80     r = snd_pcm_hw_params(pcm, hwparams);
81     assert(r == 0);
82
83     r = snd_pcm_hw_params_current(pcm, hwparams);
84     assert(r == 0);
85
86     r = snd_pcm_sw_params_current(pcm, swparams);
87     assert(r == 0);
88
89     if (cap == 0)
90       r = snd_pcm_sw_params_set_avail_min(pcm, swparams, 1);
91     else
92       r = snd_pcm_sw_params_set_avail_min(pcm, swparams, 0);
93     assert(r == 0);
94
95     r = snd_pcm_sw_params_set_period_event(pcm, swparams, 0);
96     assert(r == 0);
97
98     r = snd_pcm_hw_params_get_buffer_size(hwparams, &buffer_size);
99     assert(r == 0);
100     r = snd_pcm_sw_params_set_start_threshold(pcm, swparams, buffer_size);
101     assert(r == 0);
102
103     r = snd_pcm_sw_params_get_boundary(swparams, &boundary);
104     assert(r == 0);
105     r = snd_pcm_sw_params_set_stop_threshold(pcm, swparams, boundary);
106     assert(r == 0);
107
108     r = snd_pcm_sw_params_set_tstamp_mode(pcm, swparams, SND_PCM_TSTAMP_ENABLE);
109     assert(r == 0);
110
111     r = snd_pcm_sw_params(pcm, swparams);
112     assert(r == 0);
113
114     r = snd_pcm_prepare(pcm);
115     assert(r == 0);
116
117     r = snd_pcm_sw_params_current(pcm, swparams);
118     assert(r == 0);
119
120 /*     assert(snd_pcm_hw_params_is_monotonic(hwparams) > 0); */
121
122     n_pollfd = snd_pcm_poll_descriptors_count(pcm);
123     assert(n_pollfd > 0);
124
125     pollfds = malloc(sizeof(struct pollfd) * n_pollfd);
126     assert(pollfds);
127
128     r = snd_pcm_poll_descriptors(pcm, pollfds, n_pollfd);
129     assert(r == n_pollfd);
130
131     if (cap) {
132       r = snd_pcm_start(pcm);
133       assert(r == 0);
134     }
135
136     for (;;) {
137         snd_pcm_sframes_t avail, delay;
138         struct timespec now, timestamp;
139         unsigned short revents;
140         int handled = 0;
141         uint64_t now_us, timestamp_us;
142         snd_pcm_state_t state;
143         unsigned long long pos;
144
145         r = poll(pollfds, n_pollfd, 0);
146         assert(r >= 0);
147
148         r = snd_pcm_poll_descriptors_revents(pcm, pollfds, n_pollfd, &revents);
149         assert(r == 0);
150
151         if (cap == 0)
152           assert((revents & ~POLLOUT) == 0);
153         else
154           assert((revents & ~POLLIN) == 0);
155
156         avail = snd_pcm_avail(pcm);
157         assert(avail >= 0);
158
159         r = snd_pcm_status(pcm, status);
160         assert(r == 0);
161
162         /* This assertion fails from time to time. ALSA seems to be broken */
163 /*         assert(avail == (snd_pcm_sframes_t) snd_pcm_status_get_avail(status)); */
164 /*         printf("%lu %lu\n", (unsigned long) avail, (unsigned long) snd_pcm_status_get_avail(status)); */
165
166         snd_pcm_status_get_htstamp(status, &timestamp);
167         delay = snd_pcm_status_get_delay(status);
168         state = snd_pcm_status_get_state(status);
169
170         r = clock_gettime(CLOCK_MONOTONIC, &now);
171         assert(r == 0);
172
173         assert(!revents || avail > 0);
174
175         if ((!cap && avail) || (cap && (unsigned)avail >= buffer_size)) {
176             snd_pcm_sframes_t sframes;
177             static const uint16_t psamples[2] = { 0, 0 };
178             uint16_t csamples[2];
179
180             if (cap == 0)
181               sframes = snd_pcm_writei(pcm, psamples, 1);
182             else
183               sframes = snd_pcm_readi(pcm, csamples, 1);
184             assert(sframes == 1);
185
186             handled = 1;
187             sample_count++;
188         }
189
190         if (!handled &&
191             memcmp(&timestamp, &last_timestamp, sizeof(timestamp)) == 0 &&
192             avail == last_avail &&
193             delay == last_delay) {
194             /* This is boring */
195             continue;
196         }
197
198         now_us = timespec_us(&now);
199         timestamp_us = timespec_us(&timestamp);
200
201         if (cap == 0)
202             pos = (unsigned long long) ((sample_count - handled - delay) * 1000000LU / 44100);
203         else
204             pos = (unsigned long long) ((sample_count - handled + delay) * 1000000LU / 44100);
205
206         printf("%llu\t%llu\t%llu\t%llu\t%li\t%li\t%i\t%i\t%i\n",
207                (unsigned long long) (now_us - start_us),
208                (unsigned long long) (timestamp_us ? timestamp_us - start_us : 0),
209                pos,
210                (unsigned long long) sample_count,
211                (signed long) avail,
212                (signed long) delay,
213                revents,
214                handled,
215                state);
216
217         if (cap == 0)
218           /** When this assert is hit, most likely something bad
219            * happened, i.e. the avail jumped suddenly. */
220           assert((unsigned) avail <= buffer_size);
221
222         last_avail = avail;
223         last_delay = delay;
224         last_timestamp = timestamp;
225     }
226
227     return 0;
228 }