2 * This file is part of DisOrder.
3 * Copyright (C) 2009, 2013 Richard Kettlewell
5 * This program is free software: you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation, either version 3 of the License, or
8 * (at your option) any later version.
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
15 * You should have received a copy of the GNU General Public License
16 * along with this program. If not, see <http://www.gnu.org/licenses/>.
18 /** @file lib/uaudio-thread.c
19 * @brief Background thread for audio processing */
31 /** @brief Number of buffers
33 * Must be at least 2 and should normally be at least 3. We maintain multiple
34 * buffers so that we can read new data into one while the previous is being
37 #define UAUDIO_THREAD_BUFFERS 4
39 /** @brief Buffer data structure */
40 struct uaudio_buffer
{
41 /** @brief Pointer to sample data */
44 /** @brief Count of samples */
48 /** @brief Input buffers
50 * This is actually a ring buffer, managed by @ref uaudio_collect_buffer and
51 * @ref uaudio_play_buffer.
53 * Initially both pointers are 0. Whenever the pointers are equal, we
54 * interpreted this as meaning that there is no data stored at all. A
55 * consequence of this is that maximal occupancy is when the collect point is
56 * just before the play point, so at least one buffer is always empty (hence it
57 * being good for @ref UAUDIO_THREAD_BUFFERS to be at least 3).
59 static struct uaudio_buffer uaudio_buffers
[UAUDIO_THREAD_BUFFERS
];
61 /** @brief Buffer to read into */
62 static unsigned uaudio_collect_buffer
;
64 /** @brief Buffer to play from */
65 static unsigned uaudio_play_buffer
;
67 /** @brief Collection thread ID */
68 static pthread_t uaudio_collect_thread
;
70 /** @brief Playing thread ID */
71 static pthread_t uaudio_play_thread
;
74 static unsigned uaudio_thread_flags
;
76 static uaudio_callback
*uaudio_thread_collect_callback
;
77 static uaudio_playcallback
*uaudio_thread_play_callback
;
78 static void *uaudio_thread_userdata
;
79 static int uaudio_thread_started
;
80 static int uaudio_thread_collecting
;
81 static pthread_mutex_t uaudio_thread_lock
= PTHREAD_MUTEX_INITIALIZER
;
82 static pthread_cond_t uaudio_thread_cond
= PTHREAD_COND_INITIALIZER
;
84 /** @brief Minimum number of samples per chunk */
85 static size_t uaudio_thread_min
;
87 /** @brief Maximum number of samples per chunk */
88 static size_t uaudio_thread_max
;
90 /** @brief Set when activated, clear when paused */
91 static int uaudio_thread_activated
;
93 /** @brief Return number of buffers currently in use */
94 static int uaudio_buffers_used(void) {
95 return (uaudio_collect_buffer
- uaudio_play_buffer
) % UAUDIO_THREAD_BUFFERS
;
98 /** @brief Background thread for audio collection
100 * Collects data while activated and communicates its status via @ref
101 * uaudio_thread_collecting.
103 static void *uaudio_collect_thread_fn(void attribute((unused
)) *arg
) {
104 pthread_mutex_lock(&uaudio_thread_lock
);
105 while(uaudio_thread_started
) {
106 /* Wait until we're activatd */
107 if(!uaudio_thread_activated
) {
108 pthread_cond_wait(&uaudio_thread_cond
, &uaudio_thread_lock
);
111 /* We are definitely active now */
112 uaudio_thread_collecting
= 1;
113 pthread_cond_broadcast(&uaudio_thread_cond
);
114 while(uaudio_thread_activated
) {
115 if(uaudio_buffers_used() < UAUDIO_THREAD_BUFFERS
- 1) {
116 /* At least one buffer is available. We release the lock while
117 * collecting data so that other already-filled buffers can be played
119 struct uaudio_buffer
*const b
= &uaudio_buffers
[uaudio_collect_buffer
];
120 pthread_mutex_unlock(&uaudio_thread_lock
);
121 //fprintf(stderr, "C%d.", uaudio_collect_buffer);
123 /* Keep on trying until we get the minimum required amount of data */
125 if(uaudio_thread_activated
) {
126 while(b
->nsamples
< uaudio_thread_min
) {
127 b
->nsamples
+= uaudio_thread_collect_callback
129 + b
->nsamples
* uaudio_sample_size
,
130 uaudio_thread_max
- b
->nsamples
,
131 uaudio_thread_userdata
);
134 pthread_mutex_lock(&uaudio_thread_lock
);
135 /* Advance to next buffer */
136 uaudio_collect_buffer
= (1 + uaudio_collect_buffer
) % UAUDIO_THREAD_BUFFERS
;
138 pthread_cond_broadcast(&uaudio_thread_cond
);
140 /* No space, wait for player */
141 pthread_cond_wait(&uaudio_thread_cond
, &uaudio_thread_lock
);
143 uaudio_thread_collecting
= 0;
144 pthread_cond_broadcast(&uaudio_thread_cond
);
146 pthread_mutex_unlock(&uaudio_thread_lock
);
150 static size_t uaudio_play_samples(void *buffer
, size_t samples
, unsigned flags
) {
151 static struct timespec base
;
152 static int64_t frames_supplied
;
154 struct timespec delay_ts
;
155 double target
, delay
;
158 xgettime(CLOCK_MONOTONIC
, &base
);
159 samples
= uaudio_thread_play_callback(buffer
, samples
, flags
);
160 frames_supplied
+= samples
/ uaudio_channels
;
161 /* Set target to the approximate point at which we run out of buffered audio.
162 * If no buffer size has been specified, use 1/16th of a second. */
163 target
= (frames_supplied
- (uaudio_buffer ? uaudio_buffer
: uaudio_rate
/ 16))
164 / (double)uaudio_rate
+ ts_to_double(base
);
166 xgettime(CLOCK_MONOTONIC
, &now
);
167 delay
= target
- ts_to_double(now
);
174 fprintf(stderr, "frames supplied %ld (%lds) base %f target %f now %f want delay %g\n",
176 frames_supplied / uaudio_rate,
182 delay_ts
= double_to_ts(delay
);
183 xnanosleep(&delay_ts
, NULL
);
188 /** @brief Background thread for audio playing
190 * This thread plays data as long as there is something to play. So the
191 * buffers will drain to empty before deactivation completes.
193 static void *uaudio_play_thread_fn(void attribute((unused
)) *arg
) {
195 unsigned last_flags
= 0;
196 unsigned char zero
[uaudio_thread_max
* uaudio_sample_size
];
197 memset(zero
, 0, sizeof zero
);
199 while(uaudio_thread_started
) {
200 // If we're paused then just play silence
201 if(!uaudio_thread_activated
) {
202 pthread_mutex_unlock(&uaudio_thread_lock
);
203 unsigned flags
= UAUDIO_PAUSED
;
204 if(last_flags
& UAUDIO_PLAYING
)
205 flags
|= UAUDIO_PAUSE
;
206 uaudio_play_samples(zero
, uaudio_thread_max
, last_flags
= flags
);
207 /* We expect the play callback to block for a reasonable period */
208 pthread_mutex_lock(&uaudio_thread_lock
);
211 const int used
= uaudio_buffers_used();
215 go
= (used
== UAUDIO_THREAD_BUFFERS
- 1);
219 /* At least one buffer is filled. We release the lock while playing so
220 * that more collection can go on. */
221 struct uaudio_buffer
*const b
= &uaudio_buffers
[uaudio_play_buffer
];
222 pthread_mutex_unlock(&uaudio_thread_lock
);
223 //fprintf(stderr, "P%d.", uaudio_play_buffer);
225 while(played
< b
->nsamples
) {
226 unsigned flags
= UAUDIO_PLAYING
;
227 if(last_flags
& UAUDIO_PAUSED
)
228 flags
|= UAUDIO_RESUME
;
229 played
+= uaudio_play_samples((char *)b
->samples
230 + played
* uaudio_sample_size
,
231 b
->nsamples
- played
,
234 pthread_mutex_lock(&uaudio_thread_lock
);
235 /* Move to next buffer */
236 uaudio_play_buffer
= (1 + uaudio_play_buffer
) % UAUDIO_THREAD_BUFFERS
;
237 /* Awaken collector */
238 pthread_cond_broadcast(&uaudio_thread_cond
);
241 /* Insufficient data to play, wait for collector */
242 pthread_cond_wait(&uaudio_thread_cond
, &uaudio_thread_lock
);
243 /* (Still) re-synchronizing */
247 pthread_mutex_unlock(&uaudio_thread_lock
);
251 /** @brief Create background threads for audio processing
252 * @param callback Callback to collect audio data
253 * @param userdata Passed to @p callback
254 * @param playcallback Callback to play audio data
255 * @param min Minimum number of samples to play in a chunk
256 * @param max Maximum number of samples to play in a chunk
257 * @param flags Flags (not currently used)
259 * @p callback will be called multiple times in quick succession if necessary
260 * to gather at least @p min samples. Equally @p playcallback may be called
261 * repeatedly in quick succession to play however much was received in a single
264 void uaudio_thread_start(uaudio_callback
*callback
,
266 uaudio_playcallback
*playcallback
,
271 uaudio_thread_collect_callback
= callback
;
272 uaudio_thread_userdata
= userdata
;
273 uaudio_thread_play_callback
= playcallback
;
274 uaudio_thread_min
= min
;
275 uaudio_thread_max
= max
;
276 uaudio_thread_flags
= flags
;
277 uaudio_thread_started
= 1;
278 uaudio_thread_activated
= 0;
279 for(int n
= 0; n
< UAUDIO_THREAD_BUFFERS
; ++n
)
280 uaudio_buffers
[n
].samples
= xcalloc_noptr(uaudio_thread_max
,
282 uaudio_collect_buffer
= uaudio_play_buffer
= 0;
283 if((e
= pthread_create(&uaudio_collect_thread
,
285 uaudio_collect_thread_fn
,
287 disorder_fatal(e
, "pthread_create");
288 if((e
= pthread_create(&uaudio_play_thread
,
290 uaudio_play_thread_fn
,
292 disorder_fatal(e
, "pthread_create");
295 /** @brief Shut down background threads for audio processing */
296 void uaudio_thread_stop(void) {
299 pthread_mutex_lock(&uaudio_thread_lock
);
300 uaudio_thread_activated
= 0;
301 uaudio_thread_started
= 0;
302 pthread_cond_broadcast(&uaudio_thread_cond
);
303 pthread_mutex_unlock(&uaudio_thread_lock
);
304 pthread_join(uaudio_collect_thread
, &result
);
305 pthread_join(uaudio_play_thread
, &result
);
306 for(int n
= 0; n
< UAUDIO_THREAD_BUFFERS
; ++n
)
307 xfree(uaudio_buffers
[n
].samples
);
310 /** @brief Activate audio output */
311 void uaudio_thread_activate(void) {
312 pthread_mutex_lock(&uaudio_thread_lock
);
313 uaudio_thread_activated
= 1;
314 pthread_cond_broadcast(&uaudio_thread_cond
);
315 pthread_mutex_unlock(&uaudio_thread_lock
);
318 /** @brief Deactivate audio output */
319 void uaudio_thread_deactivate(void) {
320 pthread_mutex_lock(&uaudio_thread_lock
);
321 uaudio_thread_activated
= 0;
322 pthread_cond_broadcast(&uaudio_thread_cond
);
323 pthread_mutex_unlock(&uaudio_thread_lock
);