]>
Commit | Line | Data |
---|---|---|
cf8401db JL |
1 | /* |
2 | * Slave-clocked ALAC stream player. This file is part of Shairport. | |
3 | * Copyright (c) James Laird 2011, 2013 | |
4 | * All rights reserved. | |
5 | * | |
bdfb1c6e | 6 | * Modifications for audio synchronisation, AirPlay 2 |
28f54af2 | 7 | * and related work, copyright (c) Mike Brady 2014 -- 2023 |
08199b99 MB |
8 | * All rights reserved. |
9 | * | |
cf8401db JL |
10 | * Permission is hereby granted, free of charge, to any person |
11 | * obtaining a copy of this software and associated documentation | |
12 | * files (the "Software"), to deal in the Software without | |
13 | * restriction, including without limitation the rights to use, | |
14 | * copy, modify, merge, publish, distribute, sublicense, and/or | |
15 | * sell copies of the Software, and to permit persons to whom the | |
16 | * Software is furnished to do so, subject to the following conditions: | |
17 | * | |
18 | * The above copyright notice and this permission notice shall be | |
19 | * included in all copies or substantial portions of the Software. | |
20 | * | |
21 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, | |
22 | * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES | |
23 | * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND | |
24 | * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT | |
25 | * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, | |
26 | * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING | |
27 | * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR | |
28 | * OTHER DEALINGS IN THE SOFTWARE. | |
29 | */ | |
a2fb5d21 | 30 | |
064bd293 MB |
31 | #include <assert.h> |
32 | #include <errno.h> | |
33 | #include <fcntl.h> | |
34 | #include <inttypes.h> | |
35 | #include <limits.h> | |
36 | #include <math.h> | |
37 | #include <pthread.h> | |
8bee92a4 | 38 | #include <stdarg.h> |
a2fb5d21 JL |
39 | #include <stdio.h> |
40 | #include <stdlib.h> | |
a2fb5d21 | 41 | #include <string.h> |
a2fb5d21 | 42 | #include <sys/stat.h> |
705a0be1 | 43 | #include <sys/syslog.h> |
064bd293 MB |
44 | #include <sys/types.h> |
45 | #include <unistd.h> | |
a2fb5d21 | 46 | |
771aa1a1 MB |
47 | #include "config.h" |
48 | ||
c9b3d2a2 | 49 | #ifdef CONFIG_MBEDTLS |
62aaf074 MB |
50 | #include <mbedtls/aes.h> |
51 | #include <mbedtls/havege.h> | |
52 | #endif | |
53 | ||
c9b3d2a2 | 54 | #ifdef CONFIG_POLARSSL |
771aa1a1 MB |
55 | #include <polarssl/aes.h> |
56 | #include <polarssl/havege.h> | |
57 | #endif | |
58 | ||
c9b3d2a2 | 59 | #ifdef CONFIG_OPENSSL |
97dd0b1e | 60 | #include <openssl/aes.h> // needed for older AES stuff |
0ca5fd3c | 61 | #include <openssl/bio.h> // needed for BIO_new_mem_buf |
97dd0b1e MB |
62 | #include <openssl/err.h> // needed for ERR_error_string, ERR_get_error |
63 | #include <openssl/evp.h> // needed for EVP_PKEY_CTX_new, EVP_PKEY_sign_init, EVP_PKEY_sign | |
64 | #include <openssl/pem.h> // needed for PEM_read_bio_RSAPrivateKey, EVP_PKEY_CTX_set_rsa_padding | |
65 | #include <openssl/rsa.h> // needed for EVP_PKEY_CTX_set_rsa_padding | |
771aa1a1 MB |
66 | #endif |
67 | ||
c9b3d2a2 | 68 | #ifdef CONFIG_SOXR |
771aa1a1 MB |
69 | #include <soxr.h> |
70 | #endif | |
71 | ||
7b9cd28e YP |
72 | #ifdef CONFIG_CONVOLUTION |
73 | #include <FFTConvolver/convolver.h> | |
74 | #endif | |
75 | ||
69642bb7 | 76 | #ifdef CONFIG_METADATA_HUB |
065eada6 MB |
77 | #include "metadata_hub.h" |
78 | #endif | |
79 | ||
69642bb7 | 80 | #ifdef CONFIG_DACP_CLIENT |
df7c48f0 | 81 | #include "dacp.h" |
df7c48f0 MB |
82 | #endif |
83 | ||
a2fb5d21 | 84 | #include "common.h" |
72079ada | 85 | #include "mdns.h" |
a2fb5d21 JL |
86 | #include "player.h" |
87 | #include "rtp.h" | |
32448afc | 88 | #include "rtsp.h" |
a2fb5d21 | 89 | |
a2fb5d21 JL |
90 | #include "alac.h" |
91 | ||
c9b3d2a2 | 92 | #ifdef CONFIG_APPLE_ALAC |
945483d9 | 93 | #include "apple_alac.h" |
73e504ac | 94 | #endif |
945483d9 | 95 | |
3f779949 MB |
96 | #ifdef CONFIG_AIRPLAY_2 |
97 | #include "ptp-utilities.h" | |
98 | #endif | |
99 | ||
7b9cd28e YP |
100 | #include "loudness.h" |
101 | ||
a8639f6c MB |
102 | #include "activity_monitor.h" |
103 | ||
986f9587 | 104 | // make the first audio packet deliberately early to bias the sync error of |
54d761ff MB |
105 | // the very first packet, making the error more likely to be too early |
106 | // rather than too late. It it's too early, | |
107 | // a delay exactly compensating for it can be sent just before the | |
108 | // first packet. This should exactly compensate for the error. | |
109 | ||
110 | int64_t first_frame_early_bias = 8; | |
111 | ||
a2fb5d21 JL |
112 | // default buffer size |
113 | // needs to be a power of 2 because of the way BUFIDX(seqno) works | |
d6536a8e | 114 | // #define BUFFER_FRAMES 512 |
87a0475c | 115 | #define MAX_PACKET 2048 |
a2fb5d21 | 116 | |
771aa1a1 | 117 | // DAC buffer occupancy stuff |
4610d087 | 118 | #define DAC_BUFFER_QUEUE_MINIMUM_LENGTH 2500 |
771aa1a1 | 119 | |
d9c0028f | 120 | // static abuf_t audio_buffer[BUFFER_FRAMES]; |
a2fb5d21 JL |
121 | #define BUFIDX(seqno) ((seq_t)(seqno) % BUFFER_FRAMES) |
122 | ||
bdfb1c6e | 123 | int32_t modulo_32_offset(uint32_t from, uint32_t to) { return to - from; } |
7f6f4f44 | 124 | |
de071aef MB |
125 | void do_flush(uint32_t timestamp, rtsp_conn_info *conn); |
126 | ||
fd880056 | 127 | void ab_resync(rtsp_conn_info *conn) { |
771aa1a1 | 128 | int i; |
87a0475c | 129 | for (i = 0; i < BUFFER_FRAMES; i++) { |
498c1d6e | 130 | conn->audio_buffer[i].ready = 0; |
e2294dec | 131 | conn->audio_buffer[i].resend_request_number = 0; |
54d761ff MB |
132 | conn->audio_buffer[i].resend_time = |
133 | 0; // this is either zero or the time the last resend was requested. | |
134 | conn->audio_buffer[i].initialisation_time = | |
135 | 0; // this is either the time the packet was received or the time it was noticed the packet | |
136 | // was missing. | |
498c1d6e | 137 | conn->audio_buffer[i].sequence_number = 0; |
f2a54dd0 | 138 | } |
755e9590 | 139 | conn->ab_synced = 0; |
f06e638d | 140 | conn->last_seqno_read = -1; |
755e9590 | 141 | conn->ab_buffering = 1; |
771aa1a1 MB |
142 | } |
143 | ||
bdfb1c6e MB |
144 | // the sequence numbers will wrap pretty often. |
145 | // this returns true if the second arg is strictly after the first | |
0ac00359 | 146 | static inline int is_after(seq_t a, seq_t b) { |
bdfb1c6e MB |
147 | int16_t d = b - a; |
148 | return d > 0; | |
a2fb5d21 JL |
149 | } |
150 | ||
3cb359c7 MB |
151 | void reset_input_flow_metrics(rtsp_conn_info *conn) { |
152 | conn->play_number_after_flush = 0; | |
153 | conn->packet_count_since_flush = 0; | |
3cb359c7 MB |
154 | conn->input_frame_rate_starting_point_is_valid = 0; |
155 | conn->initial_reference_time = 0; | |
156 | conn->initial_reference_timestamp = 0; | |
157 | } | |
158 | ||
5a7b7c01 MB |
159 | void unencrypted_packet_decode(unsigned char *packet, int length, short *dest, int *outsize, |
160 | int size_limit, rtsp_conn_info *conn) { | |
161 | if (conn->stream.type == ast_apple_lossless) { | |
162 | #ifdef CONFIG_APPLE_ALAC | |
163 | if (config.use_apple_decoder) { | |
164 | if (conn->decoder_in_use != 1 << decoder_apple_alac) { | |
165 | debug(2, "Apple ALAC Decoder used on encrypted audio."); | |
166 | conn->decoder_in_use = 1 << decoder_apple_alac; | |
167 | } | |
168 | apple_alac_decode_frame(packet, length, (unsigned char *)dest, outsize); | |
169 | *outsize = *outsize * 4; // bring the size to bytes | |
170 | } else | |
171 | #endif | |
172 | { | |
173 | if (conn->decoder_in_use != 1 << decoder_hammerton) { | |
174 | debug(2, "Hammerton Decoder used on encrypted audio."); | |
175 | conn->decoder_in_use = 1 << decoder_hammerton; | |
176 | } | |
177 | alac_decode_frame(conn->decoder_info, packet, (unsigned char *)dest, outsize); | |
178 | } | |
179 | } else if (conn->stream.type == ast_uncompressed) { | |
180 | int length_to_use = length; | |
181 | if (length_to_use > size_limit) { | |
182 | warn("unencrypted_packet_decode: uncompressed audio packet too long (size: %d bytes) to " | |
183 | "process -- truncated", | |
184 | length); | |
185 | length_to_use = size_limit; | |
186 | } | |
187 | int i; | |
188 | short *source = (short *)packet; | |
189 | for (i = 0; i < (length_to_use / 2); i++) { | |
190 | *dest = ntohs(*source); | |
191 | dest++; | |
192 | source++; | |
193 | } | |
194 | *outsize = length_to_use; | |
195 | } | |
196 | } | |
197 | ||
97dd0b1e MB |
198 | #ifdef CONFIG_OPENSSL |
199 | // Thanks to | |
200 | // https://stackoverflow.com/questions/27558625/how-do-i-use-aes-cbc-encrypt-128-openssl-properly-in-ubuntu | |
201 | // for inspiration. Changed to a 128-bit key and no padding. | |
202 | ||
203 | int openssl_aes_decrypt_cbc(unsigned char *ciphertext, int ciphertext_len, unsigned char *key, | |
0ca5fd3c | 204 | unsigned char *iv, unsigned char *plaintext) { |
97dd0b1e MB |
205 | EVP_CIPHER_CTX *ctx; |
206 | int len; | |
207 | int plaintext_len = 0; | |
208 | ctx = EVP_CIPHER_CTX_new(); | |
209 | if (ctx != NULL) { | |
210 | if (EVP_DecryptInit_ex(ctx, EVP_aes_128_cbc(), NULL, key, iv) == 1) { | |
211 | EVP_CIPHER_CTX_set_padding(ctx, 0); // no padding -- always returns 1 | |
212 | // no need to allow space for padding in the output, as padding is disabled | |
213 | if (EVP_DecryptUpdate(ctx, plaintext, &len, ciphertext, ciphertext_len) == 1) { | |
214 | plaintext_len = len; | |
215 | if (EVP_DecryptFinal_ex(ctx, plaintext + len, &len) == 1) { | |
216 | plaintext_len += len; | |
217 | } else { | |
218 | debug(1, "EVP_DecryptFinal_ex error \"%s\".", ERR_error_string(ERR_get_error(), NULL)); | |
219 | } | |
220 | } else { | |
221 | debug(1, "EVP_DecryptUpdate error \"%s\".", ERR_error_string(ERR_get_error(), NULL)); | |
222 | } | |
223 | } else { | |
224 | debug(1, "EVP_DecryptInit_ex error \"%s\".", ERR_error_string(ERR_get_error(), NULL)); | |
225 | } | |
226 | EVP_CIPHER_CTX_free(ctx); | |
227 | } else { | |
228 | debug(1, "EVP_CIPHER_CTX_new error \"%s\".", ERR_error_string(ERR_get_error(), NULL)); | |
229 | } | |
230 | return plaintext_len; | |
231 | } | |
232 | #endif | |
5a7b7c01 | 233 | int audio_packet_decode(short *dest, int *destlen, uint8_t *buf, int len, rtsp_conn_info *conn) { |
adc44b25 MB |
234 | // parameters: where the decoded stuff goes, its length in samples, |
235 | // the incoming packet, the length of the incoming packet in bytes | |
236 | // destlen should contain the allowed max number of samples on entry | |
064bd293 MB |
237 | |
238 | if (len > MAX_PACKET) { | |
239 | warn("Incoming audio packet size is too large at %d; it should not exceed %d.", len, | |
240 | MAX_PACKET); | |
adc44b25 MB |
241 | return -1; |
242 | } | |
771aa1a1 | 243 | unsigned char packet[MAX_PACKET]; |
07e46565 | 244 | // unsigned char packetp[MAX_PACKET]; |
945483d9 | 245 | assert(len <= MAX_PACKET); |
d9c0028f | 246 | int reply = 0; // everything okay |
05305e15 | 247 | int outsize = conn->input_bytes_per_frame * (*destlen); // the size the output should be, in bytes |
5a7b7c01 | 248 | int maximum_possible_outsize = outsize; |
771aa1a1 | 249 | |
7d672bcf | 250 | if (conn->stream.encrypted) { |
2a1fe7af MB |
251 | unsigned char iv[16]; |
252 | int aeslen = len & ~0xf; | |
7d672bcf | 253 | memcpy(iv, conn->stream.aesiv, sizeof(iv)); |
c9b3d2a2 | 254 | #ifdef CONFIG_MBEDTLS |
7d672bcf | 255 | mbedtls_aes_crypt_cbc(&conn->dctx, MBEDTLS_AES_DECRYPT, aeslen, iv, buf, packet); |
62aaf074 | 256 | #endif |
c9b3d2a2 | 257 | #ifdef CONFIG_POLARSSL |
7d672bcf | 258 | aes_crypt_cbc(&conn->dctx, AES_DECRYPT, aeslen, iv, buf, packet); |
771aa1a1 | 259 | #endif |
c9b3d2a2 | 260 | #ifdef CONFIG_OPENSSL |
97dd0b1e | 261 | openssl_aes_decrypt_cbc(buf, aeslen, conn->stream.aeskey, iv, packet); |
771aa1a1 | 262 | #endif |
2a1fe7af | 263 | memcpy(packet + aeslen, buf + aeslen, len - aeslen); |
5a7b7c01 | 264 | unencrypted_packet_decode(packet, len, dest, &outsize, maximum_possible_outsize, conn); |
2a1fe7af | 265 | } else { |
5a7b7c01 MB |
266 | // not encrypted |
267 | unencrypted_packet_decode(buf, len, dest, &outsize, maximum_possible_outsize, conn); | |
2a1fe7af | 268 | } |
adc44b25 | 269 | |
5a7b7c01 | 270 | if (outsize > maximum_possible_outsize) { |
54d761ff MB |
271 | debug(2, |
272 | "Output from alac_decode larger (%d bytes, not frames) than expected (%d bytes) -- " | |
273 | "truncated, but buffer overflow possible! Encrypted = %d.", | |
5a7b7c01 | 274 | outsize, maximum_possible_outsize, conn->stream.encrypted); |
adc44b25 | 275 | reply = -1; // output packet is the wrong size |
945483d9 MB |
276 | } |
277 | ||
14bfba27 MB |
278 | if (conn->input_bytes_per_frame != 0) |
279 | *destlen = outsize / conn->input_bytes_per_frame; | |
280 | else | |
281 | die("Unexpectedly, conn->input_bytes_per_frame is zero."); | |
05305e15 | 282 | if ((outsize % conn->input_bytes_per_frame) != 0) |
54d761ff MB |
283 | debug(1, |
284 | "Number of audio frames (%d) does not correspond exactly to the number of bytes (%d) " | |
285 | "and the audio frame size (%d).", | |
05305e15 | 286 | *destlen, outsize, conn->input_bytes_per_frame); |
6c485fa5 | 287 | return reply; |
771aa1a1 | 288 | } |
a2fb5d21 | 289 | |
5a7b7c01 | 290 | static int init_alac_decoder(int32_t fmtp[12], rtsp_conn_info *conn) { |
72f1c3b5 | 291 | |
2260853e MB |
292 | // clang-format off |
293 | ||
064bd293 | 294 | // This is a guess, but the format of the fmtp looks identical to the format of an |
2260853e MB |
295 | // ALACSpecificCOnfig which is detailed in the file ALACMagicCookieDescription.txt |
296 | // in the Apple ALAC sample implementation | |
064bd293 MB |
297 | // Here it is: |
298 | ||
299 | /* | |
2260853e MB |
300 | |
301 | * ALAC Specific Info (24 bytes) (mandatory) | |
302 | __________________________________________________________________________________________________________________________________ | |
303 | ||
304 | The Apple Lossless codec stores specific information about the encoded stream in the ALACSpecificConfig. This | |
305 | info is vended by the encoder and is used to setup the decoder for a given encoded bitstream. | |
306 | ||
307 | When read from and written to a file, the fields of this struct must be in big-endian order. | |
308 | When vended by the encoder (and received by the decoder) the struct values will be in big-endian order. | |
309 | ||
310 | ||
311 | struct ALACSpecificConfig (defined in ALACAudioTypes.h) | |
312 | abstract This struct is used to describe codec provided information about the encoded Apple Lossless bitstream. | |
313 | It must accompany the encoded stream in the containing audio file and be provided to the decoder. | |
314 | ||
315 | field frameLength uint32_t indicating the frames per packet when no explicit frames per packet setting is | |
316 | present in the packet header. The encoder frames per packet can be explicitly set | |
317 | but for maximum compatibility, the default encoder setting of 4096 should be used. | |
318 | ||
319 | field compatibleVersion uint8_t indicating compatible version, | |
064bd293 MB |
320 | value must be set to 0 |
321 | ||
2260853e | 322 | field bitDepth uint8_t describes the bit depth of the source PCM data (maximum value = 32) |
064bd293 | 323 | |
2260853e | 324 | field pb uint8_t currently unused tuning parameter. |
064bd293 MB |
325 | value should be set to 40 |
326 | ||
2260853e MB |
327 | field mb uint8_t currently unused tuning parameter. |
328 | value should be set to 10 | |
329 | ||
330 | field kb uint8_t currently unused tuning parameter. | |
064bd293 MB |
331 | value should be set to 14 |
332 | ||
2260853e MB |
333 | field numChannels uint8_t describes the channel count (1 = mono, 2 = stereo, etc...) |
334 | when channel layout info is not provided in the 'magic cookie', a channel count > 2 | |
335 | describes a set of discreet channels with no specific ordering | |
336 | ||
337 | field maxRun uint16_t currently unused. | |
338 | value should be set to 255 | |
339 | ||
340 | field maxFrameBytes uint32_t the maximum size of an Apple Lossless packet within the encoded stream. | |
341 | value of 0 indicates unknown | |
342 | ||
343 | field avgBitRate uint32_t the average bit rate in bits per second of the Apple Lossless stream. | |
344 | value of 0 indicates unknown | |
345 | ||
346 | field sampleRate uint32_t sample rate of the encoded stream | |
347 | ||
348 | ||
349 | typedef struct ALACSpecificConfig | |
350 | { | |
351 | uint32_t frameLength; | |
352 | uint8_t compatibleVersion; | |
353 | uint8_t bitDepth; | |
354 | uint8_t pb; | |
355 | uint8_t mb; | |
356 | uint8_t kb; | |
357 | uint8_t numChannels; | |
358 | uint16_t maxRun; | |
359 | uint32_t maxFrameBytes; | |
360 | uint32_t avgBitRate; | |
361 | uint32_t sampleRate; | |
362 | ||
363 | } ALACSpecificConfig; | |
064bd293 | 364 | |
064bd293 MB |
365 | */ |
366 | ||
2260853e MB |
367 | // We are going to go on that basis |
368 | ||
fd880056 | 369 | // clang-format on |
72f1c3b5 | 370 | |
771aa1a1 MB |
371 | alac_file *alac; |
372 | ||
c2e3fa5a MB |
373 | alac = alac_create(conn->input_bit_depth, |
374 | conn->input_num_channels); // no pthread cancellation point in here | |
771aa1a1 MB |
375 | if (!alac) |
376 | return 1; | |
05305e15 | 377 | conn->decoder_info = alac; |
771aa1a1 | 378 | |
cae9337d | 379 | alac->setinfo_max_samples_per_frame = conn->max_frames_per_packet; |
87a0475c | 380 | alac->setinfo_7a = fmtp[2]; |
cae9337d | 381 | alac->setinfo_sample_size = conn->input_bit_depth; |
771aa1a1 MB |
382 | alac->setinfo_rice_historymult = fmtp[4]; |
383 | alac->setinfo_rice_initialhistory = fmtp[5]; | |
384 | alac->setinfo_rice_kmodifier = fmtp[6]; | |
87a0475c MB |
385 | alac->setinfo_7f = fmtp[7]; |
386 | alac->setinfo_80 = fmtp[8]; | |
387 | alac->setinfo_82 = fmtp[9]; | |
388 | alac->setinfo_86 = fmtp[10]; | |
771aa1a1 | 389 | alac->setinfo_8a_rate = fmtp[11]; |
c2e3fa5a | 390 | alac_allocate_buffers(alac); // no pthread cancellation point in here |
945483d9 | 391 | |
c9b3d2a2 | 392 | #ifdef CONFIG_APPLE_ALAC |
c2e3fa5a | 393 | apple_alac_init(fmtp); // no pthread cancellation point in here |
945483d9 MB |
394 | #endif |
395 | ||
771aa1a1 | 396 | return 0; |
a2fb5d21 JL |
397 | } |
398 | ||
d9c0028f | 399 | static void terminate_decoders(rtsp_conn_info *conn) { |
05305e15 | 400 | alac_free(conn->decoder_info); |
c9b3d2a2 | 401 | #ifdef CONFIG_APPLE_ALAC |
945483d9 MB |
402 | apple_alac_terminate(); |
403 | #endif | |
404 | } | |
a2fb5d21 | 405 | |
d67909b8 MB |
406 | uint64_t buffers_allocated = 0; |
407 | uint64_t buffers_released = 0; | |
d9c0028f | 408 | static void init_buffer(rtsp_conn_info *conn) { |
c5dafbd2 MB |
409 | // debug(1,"input_bytes_per_frame: %d.", conn->input_bytes_per_frame); |
410 | // debug(1,"input_bit_depth: %d.", conn->input_bit_depth); | |
771aa1a1 | 411 | int i; |
d67909b8 | 412 | for (i = 0; i < BUFFER_FRAMES; i++) { |
c5dafbd2 MB |
413 | // conn->audio_buffer[i].data = malloc(conn->input_bytes_per_frame * |
414 | // conn->max_frames_per_packet); | |
d67909b8 MB |
415 | void *allocation = malloc(8 * conn->max_frames_per_packet); |
416 | if (allocation == NULL) { | |
e8b8c6ed MB |
417 | die("could not allocate memory for audio buffers. %" PRId64 " buffers allocated, %" PRId64 |
418 | " buffers released.", | |
419 | buffers_allocated, buffers_released); | |
d67909b8 MB |
420 | } else { |
421 | conn->audio_buffer[i].data = allocation; | |
422 | buffers_allocated++; | |
423 | } | |
424 | } | |
a2fb5d21 JL |
425 | } |
426 | ||
15ba7324 | 427 | static void free_audio_buffers(rtsp_conn_info *conn) { |
771aa1a1 | 428 | int i; |
d67909b8 | 429 | for (i = 0; i < BUFFER_FRAMES; i++) { |
498c1d6e | 430 | free(conn->audio_buffer[i].data); |
d67909b8 MB |
431 | buffers_released++; |
432 | } | |
01937965 | 433 | debug(2, "%" PRId64 " buffers allocated, %" PRId64 " buffers released.", buffers_allocated, |
e8b8c6ed | 434 | buffers_released); |
c627bae0 JL |
435 | } |
436 | ||
e2294dec MB |
437 | int first_possibly_missing_frame = -1; |
438 | ||
bdfb1c6e MB |
439 | void reset_buffer(rtsp_conn_info *conn) { |
440 | debug_mutex_lock(&conn->ab_mutex, 30000, 0); | |
441 | ab_resync(conn); | |
442 | debug_mutex_unlock(&conn->ab_mutex, 0); | |
41f55ac1 | 443 | if (config.output->flush) { |
70821f81 MB |
444 | config.output->flush(); // no cancellation points |
445 | // debug(1, "reset_buffer: flush output device."); | |
41f55ac1 | 446 | } |
bdfb1c6e MB |
447 | } |
448 | ||
449 | void get_audio_buffer_size_and_occupancy(unsigned int *size, unsigned int *occupancy, | |
450 | rtsp_conn_info *conn) { | |
451 | debug_mutex_lock(&conn->ab_mutex, 30000, 0); | |
452 | *size = BUFFER_FRAMES; | |
453 | if (conn->ab_synced) { | |
454 | int16_t occ = | |
455 | conn->ab_write - conn->ab_read; // will be zero or positive if read and write are within | |
456 | // 2^15 of each other and write is at or after read | |
457 | *occupancy = occ; | |
458 | } else { | |
459 | *occupancy = 0; | |
460 | } | |
461 | debug_mutex_unlock(&conn->ab_mutex, 0); | |
462 | } | |
463 | ||
464 | void player_put_packet(int original_format, seq_t seqno, uint32_t actual_timestamp, uint8_t *data, | |
465 | int len, rtsp_conn_info *conn) { | |
fd880056 | 466 | |
bdfb1c6e MB |
467 | // if it's original format, it has a valid seqno and must be decoded |
468 | // otherwise, it can take the next seqno and doesn't need decoding. | |
469 | ||
470 | // ignore a request to flush that has been made before the first packet... | |
471 | if (conn->packet_count == 0) { | |
472 | debug_mutex_lock(&conn->flush_mutex, 1000, 1); | |
473 | conn->flush_requested = 0; | |
474 | conn->flush_rtp_timestamp = 0; | |
475 | debug_mutex_unlock(&conn->flush_mutex, 3); | |
476 | } | |
6d087255 | 477 | |
eaa98ea7 | 478 | debug_mutex_lock(&conn->ab_mutex, 30000, 0); |
40289ca6 | 479 | uint64_t time_now = get_absolute_time_in_ns(); |
c2e3fa5a | 480 | conn->packet_count++; |
f6b3c420 | 481 | conn->packet_count_since_flush++; |
e2294dec | 482 | conn->time_of_last_audio_packet = time_now; |
c2e3fa5a | 483 | if (conn->connection_state_to_output) { // if we are supposed to be processing these packets |
a68f28ac MB |
484 | abuf_t *abuf = 0; |
485 | if (!conn->ab_synced) { | |
a68f28ac MB |
486 | conn->ab_write = seqno; |
487 | conn->ab_read = seqno; | |
488 | conn->ab_synced = 1; | |
fd4cc98a | 489 | conn->first_packet_timestamp = 0; |
829ea399 | 490 | debug(2, "Connection %d: synced by first packet, seqno %u.", conn->connection_number, seqno); |
a68f28ac MB |
491 | } else if (original_format == 0) { |
492 | // if the packet is coming in original format, the sequence number is important | |
493 | // otherwise, ignore is by setting it equal to the expected sequence number in ab_write | |
494 | seqno = conn->ab_write; | |
495 | } | |
496 | if (conn->ab_write == | |
497 | seqno) { // if this is the expected packet (which could be the first packet...) | |
498 | if (conn->input_frame_rate_starting_point_is_valid == 0) { | |
499 | if ((conn->packet_count_since_flush >= 500) && (conn->packet_count_since_flush <= 510)) { | |
500 | conn->frames_inward_measurement_start_time = time_now; | |
501 | conn->frames_inward_frames_received_at_measurement_start_time = actual_timestamp; | |
502 | conn->input_frame_rate_starting_point_is_valid = 1; // valid now | |
bdfb1c6e | 503 | } |
ca562872 | 504 | } |
a68f28ac MB |
505 | conn->frames_inward_measurement_time = time_now; |
506 | conn->frames_inward_frames_received_at_measurement_time = actual_timestamp; | |
507 | abuf = conn->audio_buffer + BUFIDX(seqno); | |
7b8e6865 | 508 | conn->ab_write = seqno + 1; // move the write pointer to the next free space |
0ac00359 MB |
509 | } else if (is_after(conn->ab_write, seqno)) { // newer than expected |
510 | int32_t gap = seqno - conn->ab_write; | |
a68f28ac MB |
511 | if (gap <= 0) |
512 | debug(1, "Unexpected gap size: %d.", gap); | |
513 | int i; | |
514 | for (i = 0; i < gap; i++) { | |
0ac00359 | 515 | abuf = conn->audio_buffer + BUFIDX(conn->ab_write + i); |
a68f28ac MB |
516 | abuf->ready = 0; // to be sure, to be sure |
517 | abuf->resend_request_number = 0; | |
518 | abuf->initialisation_time = | |
519 | time_now; // this represents when the packet was noticed to be missing | |
520 | abuf->status = 1 << 0; // signifying missing | |
bdfb1c6e | 521 | abuf->resend_time = 0; |
a68f28ac MB |
522 | abuf->given_timestamp = 0; |
523 | abuf->sequence_number = 0; | |
ca562872 | 524 | } |
a68f28ac MB |
525 | abuf = conn->audio_buffer + BUFIDX(seqno); |
526 | // rtp_request_resend(ab_write, gap); | |
527 | // resend_requests++; | |
528 | conn->ab_write = seqno + 1; | |
0ac00359 | 529 | } else if (is_after(conn->ab_read, seqno)) { // older than expected but not too late |
a68f28ac MB |
530 | conn->late_packets++; |
531 | abuf = conn->audio_buffer + BUFIDX(seqno); | |
532 | } else { // too late. | |
533 | conn->too_late_packets++; | |
534 | } | |
ca562872 | 535 | |
a68f28ac MB |
536 | if (abuf) { |
537 | int datalen = conn->max_frames_per_packet; | |
538 | abuf->initialisation_time = time_now; | |
539 | abuf->resend_time = 0; | |
540 | if ((original_format != 0) && | |
541 | (audio_packet_decode(abuf->data, &datalen, data, len, conn) == 0)) { | |
542 | abuf->ready = 1; | |
543 | abuf->status = 0; // signifying that it was received | |
544 | abuf->length = datalen; | |
545 | abuf->given_timestamp = actual_timestamp; | |
546 | abuf->sequence_number = seqno; | |
547 | } else if (original_format == 0) { | |
548 | memcpy(abuf->data, data, len * conn->input_bytes_per_frame); | |
549 | abuf->ready = 1; | |
550 | abuf->status = 0; // signifying that it was received | |
551 | abuf->length = len; | |
552 | abuf->given_timestamp = actual_timestamp; | |
553 | abuf->sequence_number = seqno; | |
554 | } else { | |
555 | debug(1, "Bad audio packet detected and discarded."); | |
556 | abuf->ready = 0; | |
557 | abuf->status = 1 << 1; // bad packet, discarded | |
558 | abuf->resend_request_number = 0; | |
559 | abuf->given_timestamp = 0; | |
560 | abuf->sequence_number = 0; | |
561 | } | |
562 | } | |
563 | ||
564 | int rc = pthread_cond_signal(&conn->flowcontrol); | |
565 | if (rc) | |
566 | debug(1, "Error signalling flowcontrol."); | |
ca562872 | 567 | |
a68f28ac | 568 | // resend checks |
ca562872 MB |
569 | { |
570 | uint64_t minimum_wait_time = | |
571 | (uint64_t)(config.resend_control_first_check_time * (uint64_t)1000000000); | |
572 | uint64_t resend_repeat_interval = | |
573 | (uint64_t)(config.resend_control_check_interval_time * (uint64_t)1000000000); | |
76387f82 MB |
574 | uint64_t minimum_remaining_time = (uint64_t)( |
575 | (config.resend_control_last_check_time + config.audio_backend_buffer_desired_length) * | |
576 | (uint64_t)1000000000); | |
ca562872 MB |
577 | uint64_t latency_time = (uint64_t)(conn->latency * (uint64_t)1000000000); |
578 | latency_time = latency_time / (uint64_t)conn->input_rate; | |
7b8e6865 | 579 | |
0ac00359 MB |
580 | // find the first frame that is missing, if known |
581 | int x = conn->ab_read; | |
582 | if (first_possibly_missing_frame >= 0) { | |
583 | // if it's within the range | |
584 | int16_t buffer_size = conn->ab_write - conn->ab_read; // must be positive | |
585 | if (buffer_size >= 0) { | |
586 | int16_t position_in_buffer = first_possibly_missing_frame - conn->ab_read; | |
7b8e6865 | 587 | if ((position_in_buffer >= 0) && (position_in_buffer < buffer_size)) |
0ac00359 MB |
588 | x = first_possibly_missing_frame; |
589 | } | |
ca562872 | 590 | } |
7b8e6865 | 591 | |
ca562872 MB |
592 | first_possibly_missing_frame = -1; // has not been set |
593 | ||
594 | int missing_frame_run_count = 0; | |
595 | int start_of_missing_frame_run = -1; | |
596 | int number_of_missing_frames = 0; | |
597 | while (x != conn->ab_write) { | |
598 | abuf_t *check_buf = conn->audio_buffer + BUFIDX(x); | |
599 | if (!check_buf->ready) { | |
600 | if (first_possibly_missing_frame < 0) | |
601 | first_possibly_missing_frame = x; | |
602 | number_of_missing_frames++; | |
603 | // debug(1, "frame %u's initialisation_time is 0x%" PRIx64 ", latency_time is 0x%" | |
604 | // PRIx64 ", time_now is 0x%" PRIx64 ", minimum_remaining_time is 0x%" PRIx64 ".", x, | |
605 | // check_buf->initialisation_time, latency_time, time_now, minimum_remaining_time); | |
606 | int too_late = ((check_buf->initialisation_time < (time_now - latency_time)) || | |
607 | ((check_buf->initialisation_time - (time_now - latency_time)) < | |
608 | minimum_remaining_time)); | |
609 | int too_early = ((time_now - check_buf->initialisation_time) < minimum_wait_time); | |
610 | int too_soon_after_last_request = | |
611 | ((check_buf->resend_time != 0) && | |
612 | ((time_now - check_buf->resend_time) < | |
613 | resend_repeat_interval)); // time_now can never be less than the time_tag | |
614 | ||
615 | if (too_late) | |
616 | check_buf->status |= 1 << 2; // too late | |
617 | else | |
618 | check_buf->status &= 0xFF - (1 << 2); // not too late | |
619 | if (too_early) | |
620 | check_buf->status |= 1 << 3; // too early | |
621 | else | |
622 | check_buf->status &= 0xFF - (1 << 3); // not too early | |
623 | if (too_soon_after_last_request) | |
624 | check_buf->status |= 1 << 4; // too soon after last request | |
625 | else | |
626 | check_buf->status &= 0xFF - (1 << 4); // not too soon after last request | |
627 | ||
628 | if ((!too_soon_after_last_request) && (!too_late) && (!too_early)) { | |
629 | if (start_of_missing_frame_run == -1) { | |
630 | start_of_missing_frame_run = x; | |
631 | missing_frame_run_count = 1; | |
632 | } else { | |
633 | missing_frame_run_count++; | |
634 | } | |
635 | check_buf->resend_time = time_now; // setting the time to now because we are | |
636 | // definitely going to take action | |
637 | check_buf->resend_request_number++; | |
638 | debug(3, "Frame %d is missing with ab_read of %u and ab_write of %u.", x, conn->ab_read, | |
639 | conn->ab_write); | |
640 | } | |
641 | // if (too_late) { | |
642 | // debug(1,"too late to get missing frame %u.", x); | |
643 | // } | |
644 | } | |
645 | // if (number_of_missing_frames != 0) | |
646 | // debug(1,"check with x = %u, ab_read = %u, ab_write = %u, first_possibly_missing_frame | |
647 | // = %d.", x, conn->ab_read, conn->ab_write, first_possibly_missing_frame); | |
648 | x = (x + 1) & 0xffff; | |
649 | if (((check_buf->ready) || (x == conn->ab_write)) && (missing_frame_run_count > 0)) { | |
650 | // send a resend request | |
651 | if (missing_frame_run_count > 1) | |
652 | debug(3, "request resend of %d packets starting at seqno %u.", missing_frame_run_count, | |
653 | start_of_missing_frame_run); | |
654 | if (config.disable_resend_requests == 0) { | |
655 | debug_mutex_unlock(&conn->ab_mutex, 3); | |
656 | rtp_request_resend(start_of_missing_frame_run, missing_frame_run_count, conn); | |
657 | debug_mutex_lock(&conn->ab_mutex, 20000, 1); | |
658 | conn->resend_requests++; | |
659 | } | |
660 | start_of_missing_frame_run = -1; | |
661 | missing_frame_run_count = 0; | |
662 | } | |
663 | } | |
664 | if (number_of_missing_frames == 0) | |
665 | first_possibly_missing_frame = conn->ab_write; | |
666 | } | |
87a0475c | 667 | } |
eaa98ea7 | 668 | debug_mutex_unlock(&conn->ab_mutex, 0); |
a2fb5d21 JL |
669 | } |
670 | ||
c15c49fd MB |
671 | int32_t rand_in_range(int32_t exclusive_range_limit) { |
672 | static uint32_t lcg_prev = 12345; | |
064bd293 MB |
673 | // returns a pseudo random integer in the range 0 to (exclusive_range_limit-1) inclusive |
674 | int64_t sp = lcg_prev; | |
675 | int64_t rl = exclusive_range_limit; | |
676 | lcg_prev = lcg_prev * 69069 + 3; // crappy psrg | |
e76a6366 | 677 | sp = sp * rl; // 64 bit calculation. Interesting part is above the 32 rightmost bits; |
064bd293 | 678 | return sp >> 32; |
a2fb5d21 JL |
679 | } |
680 | ||
f7717745 | 681 | static inline void process_sample(int32_t sample, char **outp, sps_format_t format, int volume, |
d9c0028f | 682 | int dither, rtsp_conn_info *conn) { |
e9623faa | 683 | /* |
2ca6e42b MB |
684 | { |
685 | static int old_volume = 0; | |
686 | if (volume != old_volume) { | |
687 | debug(1,"Volume is now %d.",volume); | |
688 | old_volume = volume; | |
689 | } | |
e9623faa MB |
690 | } |
691 | */ | |
2ca6e42b | 692 | |
8d008fa2 | 693 | int64_t hyper_sample = sample; |
07e46565 | 694 | int result = 0; |
d9c0028f | 695 | |
7b9cd28e | 696 | if (config.loudness) { |
d9c0028f MB |
697 | hyper_sample <<= |
698 | 32; // Do not apply volume as it has already been done with the Loudness DSP filter | |
7b9cd28e YP |
699 | } else { |
700 | int64_t hyper_volume = (int64_t)volume << 16; | |
65807a8b MB |
701 | hyper_sample = hyper_sample * hyper_volume; // this is 64 bit bit multiplication -- we may need |
702 | // to dither it down to its target resolution | |
7b9cd28e | 703 | } |
d9c0028f | 704 | |
8d008fa2 MB |
705 | // next, do dither, if necessary |
706 | if (dither) { | |
064bd293 MB |
707 | |
708 | // add a TPDF dither -- see | |
85cc1bdd | 709 | // http://educypedia.karadimov.info/library/DitherExplained.pdf |
064bd293 MB |
710 | // and the discussion around https://www.hydrogenaud.io/forums/index.php?showtopic=16963&st=25 |
711 | ||
712 | // I think, for a 32 --> 16 bits, the range of | |
713 | // random numbers needs to be from -2^16 to 2^16, i.e. from -65536 to 65536 inclusive, not from | |
714 | // -32768 to +32767 | |
c8b0be30 | 715 | |
85cc1bdd | 716 | // Actually, what would be generated here is from -65535 to 65535, i.e. one less on the limits. |
064bd293 MB |
717 | |
718 | // See the original paper at | |
719 | // http://www.ece.rochester.edu/courses/ECE472/resources/Papers/Lipshitz_1992.pdf | |
720 | // by Lipshitz, Wannamaker and Vanderkooy, 1992. | |
721 | ||
07e46565 | 722 | int64_t dither_mask = 0; |
8d008fa2 | 723 | switch (format) { |
0499743b | 724 | case SPS_FORMAT_S32: |
1d32976d MB |
725 | case SPS_FORMAT_S32_LE: |
726 | case SPS_FORMAT_S32_BE: | |
85cc1bdd | 727 | dither_mask = (int64_t)1 << (64 - 32); |
064bd293 | 728 | break; |
0499743b | 729 | case SPS_FORMAT_S24: |
1d32976d MB |
730 | case SPS_FORMAT_S24_LE: |
731 | case SPS_FORMAT_S24_BE: | |
b5ee350b MB |
732 | case SPS_FORMAT_S24_3LE: |
733 | case SPS_FORMAT_S24_3BE: | |
85cc1bdd | 734 | dither_mask = (int64_t)1 << (64 - 24); |
064bd293 | 735 | break; |
0499743b | 736 | case SPS_FORMAT_S16: |
1d32976d MB |
737 | case SPS_FORMAT_S16_LE: |
738 | case SPS_FORMAT_S16_BE: | |
85cc1bdd | 739 | dither_mask = (int64_t)1 << (64 - 16); |
064bd293 MB |
740 | break; |
741 | case SPS_FORMAT_S8: | |
742 | case SPS_FORMAT_U8: | |
85cc1bdd | 743 | dither_mask = (int64_t)1 << (64 - 8); |
064bd293 | 744 | break; |
a53b4c5c MB |
745 | case SPS_FORMAT_UNKNOWN: |
746 | die("Unexpected SPS_FORMAT_UNKNOWN while calculating dither mask."); | |
20967812 | 747 | break; |
83c0405d MB |
748 | case SPS_FORMAT_AUTO: |
749 | die("Unexpected SPS_FORMAT_AUTO while calculating dither mask."); | |
750 | break; | |
1d32976d MB |
751 | case SPS_FORMAT_INVALID: |
752 | die("Unexpected SPS_FORMAT_INVALID while calculating dither mask."); | |
753 | break; | |
8d008fa2 | 754 | } |
064bd293 | 755 | dither_mask -= 1; |
185000d0 | 756 | int64_t r = r64i(); |
cf29625d | 757 | |
600cebac MB |
758 | int64_t tpdf = (r & dither_mask) - (conn->previous_random_number & dither_mask); |
759 | conn->previous_random_number = r; | |
8d008fa2 | 760 | // add dither, allowing for clipping |
064bd293 MB |
761 | if (tpdf >= 0) { |
762 | if (INT64_MAX - tpdf >= hyper_sample) | |
8d008fa2 MB |
763 | hyper_sample += tpdf; |
764 | else | |
765 | hyper_sample = INT64_MAX; | |
766 | } else { | |
064bd293 | 767 | if (INT64_MIN - tpdf <= hyper_sample) |
8d008fa2 MB |
768 | hyper_sample += tpdf; |
769 | else | |
770 | hyper_sample = INT64_MIN; | |
771 | } | |
772 | // dither is complete here | |
773 | } | |
064bd293 | 774 | |
8d008fa2 MB |
775 | // move the result to the desired position in the int64_t |
776 | char *op = *outp; | |
b5ee350b | 777 | uint8_t byt; |
8d008fa2 | 778 | switch (format) { |
1d32976d MB |
779 | case SPS_FORMAT_S32_LE: |
780 | hyper_sample >>= (64 - 32); | |
781 | byt = (uint8_t)hyper_sample; | |
782 | *op++ = byt; | |
783 | byt = (uint8_t)(hyper_sample >> 8); | |
784 | *op++ = byt; | |
785 | byt = (uint8_t)(hyper_sample >> 16); | |
786 | *op++ = byt; | |
787 | byt = (uint8_t)(hyper_sample >> 24); | |
788 | *op++ = byt; | |
789 | result = 4; | |
790 | break; | |
791 | case SPS_FORMAT_S32_BE: | |
792 | hyper_sample >>= (64 - 32); | |
793 | byt = (uint8_t)(hyper_sample >> 24); | |
794 | *op++ = byt; | |
795 | byt = (uint8_t)(hyper_sample >> 16); | |
796 | *op++ = byt; | |
797 | byt = (uint8_t)(hyper_sample >> 8); | |
798 | *op++ = byt; | |
799 | byt = (uint8_t)hyper_sample; | |
800 | *op++ = byt; | |
801 | result = 4; | |
802 | break; | |
0499743b | 803 | case SPS_FORMAT_S32: |
064bd293 MB |
804 | hyper_sample >>= (64 - 32); |
805 | *(int32_t *)op = hyper_sample; | |
806 | result = 4; | |
807 | break; | |
b5ee350b MB |
808 | case SPS_FORMAT_S24_3LE: |
809 | hyper_sample >>= (64 - 24); | |
810 | byt = (uint8_t)hyper_sample; | |
811 | *op++ = byt; | |
812 | byt = (uint8_t)(hyper_sample >> 8); | |
813 | *op++ = byt; | |
814 | byt = (uint8_t)(hyper_sample >> 16); | |
815 | *op++ = byt; | |
816 | result = 3; | |
817 | break; | |
818 | case SPS_FORMAT_S24_3BE: | |
819 | hyper_sample >>= (64 - 24); | |
820 | byt = (uint8_t)(hyper_sample >> 16); | |
821 | *op++ = byt; | |
822 | byt = (uint8_t)(hyper_sample >> 8); | |
823 | *op++ = byt; | |
824 | byt = (uint8_t)hyper_sample; | |
825 | *op++ = byt; | |
826 | result = 3; | |
827 | break; | |
1d32976d MB |
828 | case SPS_FORMAT_S24_LE: |
829 | hyper_sample >>= (64 - 24); | |
830 | byt = (uint8_t)hyper_sample; | |
831 | *op++ = byt; | |
832 | byt = (uint8_t)(hyper_sample >> 8); | |
833 | *op++ = byt; | |
834 | byt = (uint8_t)(hyper_sample >> 16); | |
835 | *op++ = byt; | |
836 | *op++ = 0; | |
837 | result = 4; | |
838 | break; | |
839 | case SPS_FORMAT_S24_BE: | |
840 | hyper_sample >>= (64 - 24); | |
841 | *op++ = 0; | |
842 | byt = (uint8_t)(hyper_sample >> 16); | |
843 | *op++ = byt; | |
844 | byt = (uint8_t)(hyper_sample >> 8); | |
845 | *op++ = byt; | |
846 | byt = (uint8_t)hyper_sample; | |
847 | *op++ = byt; | |
848 | result = 4; | |
849 | break; | |
0499743b | 850 | case SPS_FORMAT_S24: |
064bd293 MB |
851 | hyper_sample >>= (64 - 24); |
852 | *(int32_t *)op = hyper_sample; | |
853 | result = 4; | |
854 | break; | |
1d32976d MB |
855 | case SPS_FORMAT_S16_LE: |
856 | hyper_sample >>= (64 - 16); | |
857 | byt = (uint8_t)hyper_sample; | |
858 | *op++ = byt; | |
859 | byt = (uint8_t)(hyper_sample >> 8); | |
860 | *op++ = byt; | |
861 | result = 2; | |
862 | break; | |
863 | case SPS_FORMAT_S16_BE: | |
864 | hyper_sample >>= (64 - 16); | |
865 | byt = (uint8_t)(hyper_sample >> 8); | |
866 | *op++ = byt; | |
867 | byt = (uint8_t)hyper_sample; | |
868 | *op++ = byt; | |
869 | result = 2; | |
870 | break; | |
0499743b | 871 | case SPS_FORMAT_S16: |
064bd293 | 872 | hyper_sample >>= (64 - 16); |
0499743b | 873 | *(int16_t *)op = (int16_t)hyper_sample; |
064bd293 MB |
874 | result = 2; |
875 | break; | |
876 | case SPS_FORMAT_S8: | |
0499743b | 877 | hyper_sample >>= (int8_t)(64 - 8); |
064bd293 MB |
878 | *op = hyper_sample; |
879 | result = 1; | |
880 | break; | |
881 | case SPS_FORMAT_U8: | |
0499743b MB |
882 | hyper_sample >>= (uint8_t)(64 - 8); |
883 | hyper_sample += 128; | |
064bd293 MB |
884 | *op = hyper_sample; |
885 | result = 1; | |
886 | break; | |
a53b4c5c MB |
887 | case SPS_FORMAT_UNKNOWN: |
888 | die("Unexpected SPS_FORMAT_UNKNOWN while outputting samples"); | |
20967812 | 889 | break; |
83c0405d MB |
890 | case SPS_FORMAT_AUTO: |
891 | die("Unexpected SPS_FORMAT_AUTO while outputting samples"); | |
892 | break; | |
1d32976d MB |
893 | case SPS_FORMAT_INVALID: |
894 | die("Unexpected SPS_FORMAT_INVALID while outputting samples"); | |
895 | break; | |
6bf0a1d4 | 896 | } |
8d008fa2 | 897 | |
064bd293 MB |
898 | *outp += result; |
899 | } | |
8d008fa2 | 900 | |
8ed8f808 MB |
901 | void buffer_get_frame_cleanup_handler(void *arg) { |
902 | rtsp_conn_info *conn = (rtsp_conn_info *)arg; | |
eaa98ea7 | 903 | debug_mutex_unlock(&conn->ab_mutex, 0); |
8ed8f808 MB |
904 | } |
905 | ||
a2fb5d21 | 906 | // get the next frame, when available. return 0 if underrun/stream reset. |
d9c0028f | 907 | static abuf_t *buffer_get_frame(rtsp_conn_info *conn) { |
07e46565 | 908 | // int16_t buf_fill; |
7187b63e | 909 | uint64_t local_time_now; |
771aa1a1 | 910 | // struct timespec tn; |
8f34c181 | 911 | abuf_t *curframe = NULL; |
0bf34533 | 912 | int notified_buffer_empty = 0; // diagnostic only |
87a0475c | 913 | |
eaa98ea7 | 914 | debug_mutex_lock(&conn->ab_mutex, 30000, 0); |
c8c70b60 | 915 | |
7187b63e | 916 | int wait; |
064bd293 | 917 | long dac_delay = 0; // long because alsa returns a long |
c8c70b60 | 918 | |
54d761ff MB |
919 | int have_sent_prefiller_silence = |
920 | 0; // set to true when we have sent at least one silent frame to the DAC | |
a4edc649 | 921 | |
c8c70b60 MB |
922 | pthread_cleanup_push(buffer_get_frame_cleanup_handler, |
923 | (void *)conn); // undo what's been done so far | |
7187b63e | 924 | do { |
3f779949 | 925 | |
d713591d | 926 | // get the time |
40289ca6 | 927 | local_time_now = get_absolute_time_in_ns(); // type okay |
eaa98ea7 | 928 | // debug(3, "buffer_get_frame is iterating"); |
8e92da35 | 929 | |
a27f43cf | 930 | // we must have timing information before we can do anything here |
3f779949 | 931 | if (have_timestamp_timing_information(conn)) { |
87a0475c | 932 | |
3f779949 | 933 | int rco = get_requested_connection_state_to_output(); |
1b18f45f | 934 | |
3f779949 MB |
935 | if (conn->connection_state_to_output != rco) { |
936 | conn->connection_state_to_output = rco; | |
937 | // change happening | |
938 | if (conn->connection_state_to_output == 0) { // going off | |
939 | debug(2, "request flush because connection_state_to_output is off"); | |
940 | debug_mutex_lock(&conn->flush_mutex, 1000, 1); | |
941 | conn->flush_requested = 1; | |
942 | conn->flush_rtp_timestamp = 0; | |
943 | debug_mutex_unlock(&conn->flush_mutex, 3); | |
944 | } | |
1b18f45f | 945 | } |
3f779949 MB |
946 | |
947 | if (config.output->is_running) | |
948 | if (config.output->is_running() != 0) { // if the back end isn't running for any reason | |
949 | debug(2, "request flush because back end is not running"); | |
950 | debug_mutex_lock(&conn->flush_mutex, 1000, 0); | |
951 | conn->flush_requested = 1; | |
952 | conn->flush_rtp_timestamp = 0; | |
953 | debug_mutex_unlock(&conn->flush_mutex, 0); | |
f8c24c5f | 954 | } |
fd880056 | 955 | |
3f779949 MB |
956 | debug_mutex_lock(&conn->flush_mutex, 1000, 0); |
957 | pthread_cleanup_push(mutex_unlock, &conn->flush_mutex); | |
958 | if (conn->flush_requested == 1) { | |
959 | if (conn->flush_output_flushed == 0) | |
960 | if (config.output->flush) { | |
961 | config.output->flush(); // no cancellation points | |
962 | debug(2, "flush request: flush output device."); | |
963 | } | |
964 | conn->flush_output_flushed = 1; | |
965 | } | |
966 | // now check to see it the flush request is for frames in the buffer or not | |
967 | // if the first_packet_timestamp is zero, don't check | |
968 | int flush_needed = 0; | |
969 | int drop_request = 0; | |
2986b282 | 970 | if (conn->flush_requested == 1) { |
a109b587 MB |
971 | if (conn->flush_rtp_timestamp == 0) { |
972 | debug(1, "flush request: flush frame 0 -- flush assumed to be needed."); | |
973 | flush_needed = 1; | |
974 | drop_request = 1; | |
975 | } else { | |
976 | if ((conn->ab_synced) && ((conn->ab_write - conn->ab_read) > 0)) { | |
977 | abuf_t *firstPacket = conn->audio_buffer + BUFIDX(conn->ab_read); | |
978 | abuf_t *lastPacket = conn->audio_buffer + BUFIDX(conn->ab_write - 1); | |
979 | if ((firstPacket != NULL) && (firstPacket->ready)) { | |
a109b587 | 980 | uint32_t first_frame_in_buffer = firstPacket->given_timestamp; |
fd880056 MB |
981 | int32_t offset_from_first_frame = conn->flush_rtp_timestamp - first_frame_in_buffer; |
982 | if ((lastPacket != NULL) && (lastPacket->ready)) { | |
983 | // we have enough information to check if the flush is needed or can be discarded | |
984 | uint32_t last_frame_in_buffer = | |
985 | lastPacket->given_timestamp + lastPacket->length - 1; | |
986 | ||
987 | // clang-format off | |
988 | // Now we have to work out if the flush frame is in the buffer. | |
989 | ||
990 | // If it is later than the end of the buffer, flush everything and keep the | |
991 | // request active. | |
992 | ||
993 | // If it is in the buffer, we need to flush part of the buffer. | |
994 | // (Actually we flush the entire buffer and drop the request.) | |
995 | ||
996 | // If it is before the buffer, no flush is needed. Drop the request. | |
997 | // clang-format on | |
998 | ||
999 | if (offset_from_first_frame > 0) { | |
1000 | int32_t offset_to_last_frame = last_frame_in_buffer - conn->flush_rtp_timestamp; | |
1001 | if (offset_to_last_frame >= 0) { | |
1002 | debug(2, | |
1003 | "flush request: flush frame %u active -- buffer contains %u frames, from " | |
1004 | "%u to %u.", | |
1005 | conn->flush_rtp_timestamp, | |
1006 | last_frame_in_buffer - first_frame_in_buffer + 1, first_frame_in_buffer, | |
1007 | last_frame_in_buffer); | |
1008 | ||
1009 | // We need to drop all complete frames leading up to the frame containing | |
1010 | // the flush request frame. | |
1011 | int32_t offset_to_flush_frame = 0; | |
1012 | abuf_t *current_packet = NULL; | |
1013 | do { | |
1014 | current_packet = conn->audio_buffer + BUFIDX(conn->ab_read); | |
1015 | if (current_packet != NULL) { | |
1016 | uint32_t last_frame_in_current_packet = | |
1017 | current_packet->given_timestamp + current_packet->length - 1; | |
1018 | offset_to_flush_frame = | |
1019 | conn->flush_rtp_timestamp - last_frame_in_current_packet; | |
1020 | if (offset_to_flush_frame > 0) { | |
1021 | debug(2, | |
1022 | "flush to %u request: flush buffer %u, from " | |
1023 | "%u to %u. ab_write is: %u.", | |
1024 | conn->flush_rtp_timestamp, conn->ab_read, | |
1025 | current_packet->given_timestamp, | |
1026 | current_packet->given_timestamp + current_packet->length - 1, | |
1027 | conn->ab_write); | |
1028 | conn->ab_read++; | |
1029 | } | |
1030 | } else { | |
1031 | debug(1, "NULL current_packet"); | |
1032 | } | |
1033 | } while ((current_packet == NULL) || (offset_to_flush_frame > 0)); | |
1034 | // now remove any frames from the buffer that are before the flush frame itself. | |
1035 | int32_t frames_to_remove = | |
1036 | conn->flush_rtp_timestamp - current_packet->given_timestamp; | |
1037 | if (frames_to_remove > 0) { | |
1038 | debug(2, "%u frames to remove from current buffer", frames_to_remove); | |
1039 | void *dest = (void *)current_packet->data; | |
1040 | void *source = dest + conn->input_bytes_per_frame * frames_to_remove; | |
1041 | size_t frames_remaining = (current_packet->length - frames_to_remove); | |
1042 | memmove(dest, source, frames_remaining * conn->input_bytes_per_frame); | |
1043 | current_packet->given_timestamp = conn->flush_rtp_timestamp; | |
1044 | current_packet->length = frames_remaining; | |
1045 | } | |
1046 | debug( | |
1047 | 2, | |
1048 | "flush request: flush frame %u complete -- buffer contains %u frames, from " | |
1049 | "%u to %u -- flushed to %u in buffer %u, with %u frames remaining.", | |
1050 | conn->flush_rtp_timestamp, last_frame_in_buffer - first_frame_in_buffer + 1, | |
1051 | first_frame_in_buffer, last_frame_in_buffer, | |
1052 | current_packet->given_timestamp, conn->ab_read, | |
1053 | last_frame_in_buffer - current_packet->given_timestamp + 1); | |
1054 | drop_request = 1; | |
1055 | } else { | |
1056 | if (conn->flush_rtp_timestamp == last_frame_in_buffer + 1) { | |
a109b587 MB |
1057 | debug( |
1058 | 2, | |
fd880056 MB |
1059 | "flush request: flush frame %u completed -- buffer contained %u frames, " |
1060 | "from " | |
3f779949 MB |
1061 | "%u to %u", |
1062 | conn->flush_rtp_timestamp, | |
1063 | last_frame_in_buffer - first_frame_in_buffer + 1, first_frame_in_buffer, | |
1064 | last_frame_in_buffer); | |
a109b587 | 1065 | drop_request = 1; |
a109b587 MB |
1066 | } else { |
1067 | debug(2, | |
1068 | "flush request: flush frame %u pending -- buffer contains %u frames, " | |
1069 | "from " | |
1070 | "%u to %u", | |
1071 | conn->flush_rtp_timestamp, | |
1072 | last_frame_in_buffer - first_frame_in_buffer + 1, first_frame_in_buffer, | |
1073 | last_frame_in_buffer); | |
a109b587 | 1074 | } |
fd880056 | 1075 | flush_needed = 1; |
3f779949 | 1076 | } |
fd880056 MB |
1077 | } else { |
1078 | debug(2, | |
1079 | "flush request: flush frame %u expired -- buffer contains %u frames, " | |
1080 | "from %u " | |
1081 | "to %u", | |
1082 | conn->flush_rtp_timestamp, last_frame_in_buffer - first_frame_in_buffer + 1, | |
1083 | first_frame_in_buffer, last_frame_in_buffer); | |
1084 | drop_request = 1; | |
3f779949 | 1085 | } |
ca562872 MB |
1086 | } |
1087 | } | |
a109b587 MB |
1088 | } else { |
1089 | debug(3, | |
1090 | "flush request: flush frame %u -- buffer not synced or empty: synced: %d, " | |
1091 | "ab_read: " | |
1092 | "%u, ab_write: %u", | |
1093 | conn->flush_rtp_timestamp, conn->ab_synced, conn->ab_read, conn->ab_write); | |
1094 | conn->flush_requested = 0; // remove the request | |
1095 | // leave flush request pending and don't do a buffer flush, because there isn't one | |
ca562872 | 1096 | } |
3f779949 | 1097 | } |
ca562872 | 1098 | } |
3f779949 MB |
1099 | if (flush_needed) { |
1100 | debug(2, "flush request: flush done."); | |
1101 | ab_resync(conn); // no cancellation points | |
1102 | conn->first_packet_timestamp = 0; | |
1103 | conn->first_packet_time_to_play = 0; | |
1104 | conn->time_since_play_started = 0; | |
1105 | have_sent_prefiller_silence = 0; | |
1106 | dac_delay = 0; | |
1107 | } | |
1108 | if (drop_request) { | |
3f779949 MB |
1109 | conn->flush_requested = 0; |
1110 | conn->flush_rtp_timestamp = 0; | |
1111 | conn->flush_output_flushed = 0; | |
1112 | } | |
1113 | pthread_cleanup_pop(1); // unlock the conn->flush_mutex | |
fd880056 MB |
1114 | |
1115 | // skip out-of-date frames, and even more if we haven't seen the first frame | |
1116 | int out_of_date = 1; | |
1117 | uint32_t should_be_frame; | |
1118 | ||
1119 | uint64_t time_to_aim_for = local_time_now; | |
1120 | uint64_t desired_lead_time = 120000000; | |
1121 | if (conn->first_packet_timestamp == 0) | |
1122 | time_to_aim_for = time_to_aim_for + desired_lead_time; | |
1123 | ||
1124 | while ((conn->ab_synced) && ((conn->ab_write - conn->ab_read) > 0) && (out_of_date != 0)) { | |
1125 | abuf_t *thePacket = conn->audio_buffer + BUFIDX(conn->ab_read); | |
1126 | if ((thePacket != NULL) && (thePacket->ready)) { | |
1127 | local_time_to_frame(time_to_aim_for, &should_be_frame, conn); | |
1128 | // debug(1,"should_be frame is %u.",should_be_frame); | |
1129 | int32_t frame_difference = thePacket->given_timestamp - should_be_frame; | |
1130 | if (frame_difference < 0) { | |
1131 | debug(2, "Dropping out of date packet %u with timestamp %u. Lead time is %f seconds.", | |
1132 | conn->ab_read, thePacket->given_timestamp, | |
1133 | frame_difference * 1.0 / 44100.0 + desired_lead_time * 0.000000001); | |
1134 | conn->ab_read++; | |
1135 | } else { | |
1136 | if (conn->first_packet_timestamp == 0) | |
1137 | debug(2, "Accepting packet %u with timestamp %u. Lead time is %f seconds.", | |
1138 | conn->ab_read, thePacket->given_timestamp, | |
1139 | frame_difference * 1.0 / 44100.0 + desired_lead_time * 0.000000001); | |
1140 | out_of_date = 0; | |
1141 | } | |
1142 | } else { | |
1143 | debug(2, "Packet %u empty or not ready.", conn->ab_read); | |
1144 | conn->ab_read++; | |
1145 | } | |
1146 | } | |
1147 | ||
3f779949 MB |
1148 | if (conn->ab_synced) { |
1149 | curframe = conn->audio_buffer + BUFIDX(conn->ab_read); | |
fd880056 MB |
1150 | if (curframe != NULL) { |
1151 | uint64_t should_be_time; | |
1152 | frame_to_local_time(curframe->given_timestamp, &should_be_time, conn); | |
1153 | int64_t time_difference = should_be_time - local_time_now; | |
1154 | debug(3, "Check packet from buffer %u, timestamp %u, %f seconds ahead.", conn->ab_read, | |
1155 | curframe->given_timestamp, 0.000000001 * time_difference); | |
1156 | } else { | |
1157 | debug(3, "Check packet from buffer %u, empty.", conn->ab_read); | |
1158 | } | |
3f779949 MB |
1159 | |
1160 | if ((conn->ab_read != conn->ab_write) && | |
1161 | (curframe->ready)) { // it could be synced and empty, under | |
1162 | // exceptional circumstances, with the | |
1163 | // frame unused, thus apparently ready | |
1164 | ||
1165 | if (curframe->sequence_number != conn->ab_read) { | |
1166 | // some kind of sync problem has occurred. | |
1167 | if (BUFIDX(curframe->sequence_number) == BUFIDX(conn->ab_read)) { | |
1168 | // it looks like aliasing has happened | |
1169 | // jump to the new incoming stuff... | |
1170 | conn->ab_read = curframe->sequence_number; | |
1171 | debug(1, "Aliasing of buffer index -- reset."); | |
1172 | } else { | |
1173 | debug(1, "Inconsistent sequence numbers detected"); | |
1174 | } | |
e0a4e5cd | 1175 | } |
87a0475c | 1176 | } |
ccc4fe09 | 1177 | |
3f779949 MB |
1178 | if ((curframe) && (curframe->ready)) { |
1179 | notified_buffer_empty = 0; // at least one buffer now -- diagnostic only. | |
1180 | if (conn->ab_buffering) { // if we are getting packets but not yet forwarding them to the | |
1181 | // player | |
e8e81a8b | 1182 | if (conn->first_packet_timestamp == 0) { // if this is the very first packet |
e8e81a8b MB |
1183 | conn->first_packet_timestamp = |
1184 | curframe->given_timestamp; // we will keep buffering until we are | |
1185 | // supposed to start playing this | |
fd880056 | 1186 | |
e8e81a8b MB |
1187 | // Here, calculate when we should start playing. We need to know when to allow the |
1188 | // packets to be sent to the player. | |
dfd90bac | 1189 | |
e8e81a8b MB |
1190 | // every second or so, we get a reference on when a particular packet should be |
1191 | // played. | |
87a0475c | 1192 | |
e8e81a8b MB |
1193 | // It probably won't be the timestamp of our first packet, however, so we might |
1194 | // have to do some calculations. | |
87a0475c | 1195 | |
e8e81a8b MB |
1196 | // To calculate when the first packet will be played, we figure out the exact time |
1197 | // the packet should be played according to its timestamp and the reference time. | |
1198 | // The desired latency, typically 88200 frames, will be calculated for in rtp.c, | |
1199 | // and any desired backend latency offset included in it there. | |
87a0475c | 1200 | |
e8e81a8b | 1201 | uint64_t should_be_time; |
a4edc649 | 1202 | |
e8e81a8b MB |
1203 | frame_to_local_time(conn->first_packet_timestamp, // this will go modulo 2^32 |
1204 | &should_be_time, conn); | |
6bad1b3b | 1205 | |
e8e81a8b | 1206 | conn->first_packet_time_to_play = should_be_time; |
a8caa0f9 | 1207 | |
e8e81a8b | 1208 | int64_t lt = conn->first_packet_time_to_play - local_time_now; |
3870195c | 1209 | |
fd880056 MB |
1210 | // can't be too late because we skipped late packets already, FLW. |
1211 | debug(2, "Connection %d: Lead time for first frame %" PRId64 ": %f seconds.", | |
1212 | conn->connection_number, conn->first_packet_timestamp, lt * 0.000000001); | |
1213 | #ifdef CONFIG_METADATA | |
1214 | // say we have started receiving frames here | |
fd880056 MB |
1215 | send_ssnc_metadata( |
1216 | 'pffr', NULL, 0, | |
1217 | 0); // "first frame received", but don't wait if the queue is locked | |
1218 | #endif | |
9c4ed545 | 1219 | } |
9c4ed545 | 1220 | |
3f779949 MB |
1221 | if (conn->first_packet_time_to_play != 0) { |
1222 | // Now that we know the timing of the first packet... | |
1223 | if (config.output->delay) { | |
1224 | // and that the output device is capable of synchronization... | |
2dd18416 | 1225 | |
3f779949 MB |
1226 | // We may send packets of |
1227 | // silence from now until the time the first audio packet should be sent | |
1228 | // and then we will send the first packet, which will be followed by | |
1229 | // the subsequent packets. | |
1230 | // here, we figure out whether and what silence to send. | |
1b18f45f | 1231 | |
3f779949 | 1232 | uint64_t should_be_time; |
ca562872 | 1233 | |
3f779949 MB |
1234 | // readjust first packet time to play |
1235 | frame_to_local_time(conn->first_packet_timestamp, // this will go modulo 2^32 | |
1236 | &should_be_time, conn); | |
ca562872 | 1237 | |
3f779949 MB |
1238 | int64_t change_in_should_be_time = |
1239 | (int64_t)(should_be_time - conn->first_packet_time_to_play); | |
ca562872 | 1240 | |
3f779949 MB |
1241 | if (fabs(0.000001 * change_in_should_be_time) > |
1242 | 0.001) // the clock drift estimation might be nudging the estimate, and we can | |
1243 | // ignore this unless if's more than a microsecond | |
1244 | debug(2, | |
6d1369a4 | 1245 | "Change in estimated first_packet_time: %f milliseconds for first_packet.", |
3f779949 | 1246 | 0.000001 * change_in_should_be_time); |
ca562872 | 1247 | |
3f779949 | 1248 | conn->first_packet_time_to_play = should_be_time; |
ca562872 | 1249 | |
3f779949 MB |
1250 | int64_t lead_time = |
1251 | conn->first_packet_time_to_play - local_time_now; // negative means late | |
1252 | if (lead_time < 0) { | |
1253 | debug(1, "Gone past starting time for %u by %" PRId64 " nanoseconds.", | |
1254 | conn->first_packet_timestamp, -lead_time); | |
1255 | conn->ab_buffering = 0; | |
1256 | } else { | |
1257 | // do some calculations | |
1258 | if ((config.audio_backend_silent_lead_in_time_auto == 1) || | |
1259 | (lead_time <= | |
1260 | (int64_t)(config.audio_backend_silent_lead_in_time * (int64_t)1000000000))) { | |
1261 | // debug(1, "Lead time: %" PRId64 " nanoseconds.", lead_time); | |
1262 | int resp = 0; | |
1263 | dac_delay = 0; | |
1264 | if (have_sent_prefiller_silence != 0) | |
1265 | resp = config.output->delay( | |
1266 | &dac_delay); // we know the output device must have a delay function | |
1267 | if (resp == 0) { | |
1268 | int64_t gross_frame_gap = | |
1269 | ((conn->first_packet_time_to_play - local_time_now) * | |
1270 | config.output_rate) / | |
1271 | 1000000000; | |
1272 | int64_t exact_frame_gap = gross_frame_gap - dac_delay; | |
1273 | int64_t frames_needed_to_maintain_desired_buffer = | |
1274 | (int64_t)(config.audio_backend_buffer_desired_length * | |
1275 | config.output_rate) - | |
1276 | dac_delay; | |
1277 | // below, remember that exact_frame_gap and | |
1278 | // frames_needed_to_maintain_desired_buffer could both be negative | |
1279 | int64_t fs = frames_needed_to_maintain_desired_buffer; | |
1280 | ||
1281 | // if there isn't enough time to have the desired buffer size | |
1282 | if (exact_frame_gap <= frames_needed_to_maintain_desired_buffer) { | |
1283 | fs = conn->max_frames_per_packet * 2; | |
ca562872 | 1284 | } |
3f779949 MB |
1285 | // if we are very close to the end of buffering, i.e. within two |
1286 | // frame-lengths, add the remaining silence needed and end buffering | |
1287 | if (exact_frame_gap <= conn->max_frames_per_packet * 2) { | |
1288 | fs = exact_frame_gap; | |
1289 | if (fs > first_frame_early_bias) | |
1290 | fs = fs - first_frame_early_bias; // deliberately make the first packet a | |
1291 | // tiny bit early so that the player may | |
1292 | // compensate for it at the last minute | |
1293 | conn->ab_buffering = 0; | |
1294 | } | |
1295 | void *silence; | |
1296 | if (fs > 0) { | |
1297 | silence = malloc(conn->output_bytes_per_frame * fs); | |
1298 | if (silence == NULL) | |
1299 | debug(1, "Failed to allocate %d byte silence buffer.", fs); | |
1300 | else { | |
1301 | // generate frames of silence with dither if necessary | |
1302 | conn->previous_random_number = generate_zero_frames( | |
1303 | silence, fs, config.output_format, conn->enable_dither, | |
1304 | conn->previous_random_number); | |
fd880056 | 1305 | config.output->play(silence, fs, play_samples_are_untimed, 0, 0); |
b4d676fe | 1306 | debug(3, "Sent %" PRId64 " frames of silence", fs); |
3f779949 MB |
1307 | free(silence); |
1308 | have_sent_prefiller_silence = 1; | |
ca562872 MB |
1309 | } |
1310 | } | |
1311 | } else { | |
3f779949 MB |
1312 | |
1313 | if (resp == sps_extra_code_output_stalled) { | |
d6536a8e MB |
1314 | if (config.unfixable_error_reported == 0) { |
1315 | config.unfixable_error_reported = 1; | |
3f779949 MB |
1316 | if (config.cmd_unfixable) { |
1317 | command_execute(config.cmd_unfixable, "output_device_stalled", 1); | |
1318 | } else { | |
7b8e293f | 1319 | die("an unrecoverable error, \"output_device_stalled\", has been " |
d6536a8e | 1320 | "detected."); |
3f779949 MB |
1321 | } |
1322 | } | |
1323 | } else { | |
7592e237 | 1324 | debug(3, "Unexpected response to getting dac delay: %d.", resp); |
3f779949 | 1325 | } |
ca562872 MB |
1326 | } |
1327 | } | |
1328 | } | |
3f779949 MB |
1329 | } else { |
1330 | // if the output device doesn't have a delay, we simply send the lead-in | |
1331 | int64_t lead_time = | |
1332 | conn->first_packet_time_to_play - local_time_now; // negative if we are late | |
1333 | void *silence; | |
1334 | int64_t frame_gap = (lead_time * config.output_rate) / 1000000000; | |
1335 | // debug(1,"%d frames needed.",frame_gap); | |
1336 | while (frame_gap > 0) { | |
1337 | ssize_t fs = config.output_rate / 10; | |
1338 | if (fs > frame_gap) | |
1339 | fs = frame_gap; | |
1340 | ||
1341 | silence = malloc(conn->output_bytes_per_frame * fs); | |
1342 | if (silence == NULL) | |
1343 | debug(1, "Failed to allocate %d frame silence buffer.", fs); | |
1344 | else { | |
1345 | // debug(1, "No delay function -- outputting %d frames of silence.", fs); | |
1346 | conn->previous_random_number = | |
1347 | generate_zero_frames(silence, fs, config.output_format, conn->enable_dither, | |
1348 | conn->previous_random_number); | |
fd880056 | 1349 | config.output->play(silence, fs, play_samples_are_untimed, 0, 0); |
3f779949 MB |
1350 | free(silence); |
1351 | } | |
1352 | frame_gap -= fs; | |
ca562872 | 1353 | } |
3f779949 | 1354 | conn->ab_buffering = 0; |
ca562872 | 1355 | } |
ca562872 | 1356 | } |
2239efe8 | 1357 | #ifdef CONFIG_METADATA |
3f779949 | 1358 | if (conn->ab_buffering == 0) { |
3f779949 MB |
1359 | send_ssnc_metadata('prsm', NULL, 0, |
1360 | 0); // "resume", but don't wait if the queue is locked | |
1361 | } | |
ca562872 | 1362 | #endif |
3f779949 | 1363 | } |
9c4ed545 MB |
1364 | } |
1365 | } | |
87a0475c | 1366 | |
e8e81a8b MB |
1367 | // Here, we work out whether to release a packet or wait |
1368 | // We release a packet when the time is right. | |
87a0475c | 1369 | |
e8e81a8b MB |
1370 | // To work out when the time is right, we need to take account of (1) the actual time the |
1371 | // packet should be released, (2) the latency requested, (3) the audio backend latency offset | |
1372 | // and (4) the desired length of the audio backend's buffer | |
5f009106 | 1373 | |
e8e81a8b MB |
1374 | // The time is right if the current time is later or the same as |
1375 | // The packet time + (latency + latency offset - backend_buffer_length). | |
1376 | // Note: the last three items are expressed in frames and must be converted to time. | |
1377 | ||
1378 | int do_wait = 0; // don't wait unless we can really prove we must | |
3f779949 MB |
1379 | if ((conn->ab_synced) && (curframe) && (curframe->ready) && (curframe->given_timestamp)) { |
1380 | do_wait = 1; // if the current frame exists and is ready, then wait unless it's time to let | |
1381 | // it go... | |
5141e2f5 | 1382 | |
3f779949 | 1383 | // here, get the time to play the current frame. |
8cabb16f | 1384 | |
3f779949 | 1385 | if (have_timestamp_timing_information(conn)) { // if we have a reference time |
5141e2f5 | 1386 | |
3f779949 | 1387 | uint64_t time_to_play; |
a8caa0f9 | 1388 | |
3f779949 MB |
1389 | // we must enable packets to be released early enough for the |
1390 | // audio buffer to be filled to the desired length | |
a8caa0f9 | 1391 | |
3f779949 MB |
1392 | uint32_t buffer_latency_offset = |
1393 | (uint32_t)(config.audio_backend_buffer_desired_length * conn->input_rate); | |
1394 | frame_to_local_time(curframe->given_timestamp - | |
1395 | buffer_latency_offset, // this will go modulo 2^32 | |
1396 | &time_to_play, conn); | |
1b18f45f | 1397 | |
3f779949 MB |
1398 | if (local_time_now >= time_to_play) { |
1399 | do_wait = 0; | |
1400 | } | |
1401 | // here, do a sanity check. if the time_to_play is not within a few seconds of the | |
1402 | // time now, the frame is probably not meant to be there, so let it go. | |
1403 | if (do_wait != 0) { | |
1404 | // this is a hack. | |
1405 | // we subtract two 2^n unsigned numbers and get a signed 2^n result. | |
1406 | // If we think of the calculation as occurring in modulo 2^n arithmetic | |
1407 | // then the signed result's magnitude represents the shorter distance around | |
1408 | // the modulo wheel of values from one number to the other. | |
1409 | // The sign indicates the direction: positive means clockwise (upwards) from the | |
1410 | // second number to the first (i.e. the first number comes "after" the second). | |
1411 | ||
1412 | int64_t time_difference = local_time_now - time_to_play; | |
1413 | if ((time_difference > 10000000000) || (time_difference < -10000000000)) { | |
1414 | debug(2, | |
1415 | "crazy time interval of %f seconds between time now: 0x%" PRIx64 | |
1416 | " and time of packet: %" PRIx64 ".", | |
1417 | 0.000000001 * time_difference, local_time_now, time_to_play); | |
1418 | debug(2, "packet rtptime: %u, reference_timestamp: %u", curframe->given_timestamp, | |
1419 | conn->anchor_rtptime); | |
1420 | ||
1421 | do_wait = 0; // let it go | |
1422 | } | |
bdfb1c6e MB |
1423 | } |
1424 | } | |
87a0475c | 1425 | } |
3f779949 MB |
1426 | if (do_wait == 0) |
1427 | if ((conn->ab_synced != 0) && (conn->ab_read == conn->ab_write)) { // the buffer is empty! | |
1428 | if (notified_buffer_empty == 0) { | |
1ca2487b | 1429 | debug(2, "Connection %d: Buffer Empty", conn->connection_number); |
3f779949 MB |
1430 | notified_buffer_empty = 1; |
1431 | // reset_input_flow_metrics(conn); // don't do a full flush parameters reset | |
1432 | conn->initial_reference_time = 0; | |
1433 | conn->initial_reference_timestamp = 0; | |
fd880056 | 1434 | conn->first_packet_timestamp = 0; // make sure the first packet isn't late |
3f779949 MB |
1435 | } |
1436 | do_wait = 1; | |
0bf34533 | 1437 | } |
3f779949 MB |
1438 | wait = (conn->ab_buffering || (do_wait != 0) || (!conn->ab_synced)); |
1439 | } else { | |
e8e81a8b | 1440 | wait = 1; // keep waiting until the timing information becomes available |
3f779949 | 1441 | } |
7187b63e | 1442 | if (wait) { |
73eec0a1 MB |
1443 | if (conn->input_rate == 0) |
1444 | die("input_rate is zero -- should never happen!"); | |
40289ca6 | 1445 | uint64_t time_to_wait_for_wakeup_ns = |
fd880056 | 1446 | 1000000000 / conn->input_rate; // this is time period of one frame |
a1dabd79 | 1447 | time_to_wait_for_wakeup_ns *= 12 * 352; // two full 352-frame packets |
fd880056 | 1448 | time_to_wait_for_wakeup_ns /= 3; // two thirds of a packet time |
87a0475c | 1449 | |
283e4930 | 1450 | #ifdef COMPILE_FOR_LINUX_AND_FREEBSD_AND_CYGWIN_AND_OPENBSD |
56bef8e7 | 1451 | uint64_t time_of_wakeup_ns = get_realtime_in_ns() + time_to_wait_for_wakeup_ns; |
40289ca6 MB |
1452 | uint64_t sec = time_of_wakeup_ns / 1000000000; |
1453 | uint64_t nsec = time_of_wakeup_ns % 1000000000; | |
87a0475c | 1454 | |
771aa1a1 MB |
1455 | struct timespec time_of_wakeup; |
1456 | time_of_wakeup.tv_sec = sec; | |
1457 | time_of_wakeup.tv_nsec = nsec; | |
cdb4d384 | 1458 | |
c8c70b60 MB |
1459 | int rc = pthread_cond_timedwait(&conn->flowcontrol, &conn->ab_mutex, |
1460 | &time_of_wakeup); // this is a pthread cancellation point | |
95f0f012 | 1461 | if ((rc != 0) && (rc != ETIMEDOUT)) |
497d49dd | 1462 | debug(3, "pthread_cond_timedwait returned error code %d.", rc); |
771aa1a1 MB |
1463 | #endif |
1464 | #ifdef COMPILE_FOR_OSX | |
40289ca6 MB |
1465 | uint64_t sec = time_to_wait_for_wakeup_ns / 1000000000; |
1466 | uint64_t nsec = time_to_wait_for_wakeup_ns % 1000000000; | |
771aa1a1 MB |
1467 | struct timespec time_to_wait; |
1468 | time_to_wait.tv_sec = sec; | |
1469 | time_to_wait.tv_nsec = nsec; | |
f06e638d | 1470 | pthread_cond_timedwait_relative_np(&conn->flowcontrol, &conn->ab_mutex, &time_to_wait); |
771aa1a1 | 1471 | #endif |
87a0475c | 1472 | } |
7187b63e MB |
1473 | } while (wait); |
1474 | ||
07e46565 | 1475 | // seq_t read = conn->ab_read; |
8f34c181 MB |
1476 | if (curframe) { |
1477 | if (!curframe->ready) { | |
1478 | // debug(1, "Supplying a silent frame for frame %u", read); | |
1479 | conn->missing_packets++; | |
1480 | curframe->given_timestamp = 0; // indicate a silent frame should be substituted | |
1481 | } | |
1482 | curframe->ready = 0; | |
7187b63e | 1483 | } |
bdfb1c6e | 1484 | conn->ab_read++; |
c8c70b60 | 1485 | pthread_cleanup_pop(1); |
7187b63e | 1486 | return curframe; |
a2fb5d21 JL |
1487 | } |
1488 | ||
c7c794c7 MB |
1489 | static inline int32_t mean_32(int32_t a, int32_t b) { |
1490 | int64_t al = a; | |
1491 | int64_t bl = b; | |
1492 | int64_t mean = (al + bl) / 2; | |
1493 | int32_t r = (int32_t)mean; | |
1494 | if (r != mean) | |
0ac00359 | 1495 | debug(1, "Error calculating average of two int32_t values: %d, %d.", a, b); |
c7c794c7 MB |
1496 | return r; |
1497 | } | |
1498 | ||
064bd293 MB |
1499 | // this takes an array of signed 32-bit integers and (a) removes or inserts a frame as specified in |
1500 | // stuff, | |
8d008fa2 | 1501 | // (b) multiplies each sample by the fixedvolume (a 16-bit quantity) |
64371bb8 | 1502 | // (c) dithers the result to the output size 32/24/16/8 bits |
8d008fa2 | 1503 | // (d) outputs the result in the approprate format |
b5ee350b | 1504 | // formats accepted so far include U8, S8, S16, S24, S24_3LE, S24_3BE and S32 |
8d008fa2 | 1505 | |
771aa1a1 | 1506 | // stuff: 1 means add 1; 0 means do nothing; -1 means remove 1 |
f7717745 | 1507 | static int stuff_buffer_basic_32(int32_t *inptr, int length, sps_format_t l_output_format, |
d9c0028f | 1508 | char *outptr, int stuff, int dither, rtsp_conn_info *conn) { |
14bfba27 MB |
1509 | if (length < 3) |
1510 | die("buffer length expected to be 3 or more, but is %d!", length); | |
c7c794c7 | 1511 | int tstuff = stuff; |
8d008fa2 | 1512 | char *l_outptr = outptr; |
064bd293 | 1513 | if ((stuff > 1) || (stuff < -1) || (length < 100)) { |
c7c794c7 MB |
1514 | // debug(1, "Stuff argument to stuff_buffer must be from -1 to +1 and length >100."); |
1515 | tstuff = 0; // if any of these conditions hold, don't stuff anything/ | |
1516 | } | |
064bd293 | 1517 | |
c7c794c7 MB |
1518 | int i; |
1519 | int stuffsamp = length; | |
1520 | if (tstuff) | |
1521 | // stuffsamp = rand() % (length - 1); | |
1522 | stuffsamp = | |
1523 | (rand() % (length - 2)) + 1; // ensure there's always a sample before and after the item | |
1524 | ||
c7c794c7 | 1525 | for (i = 0; i < stuffsamp; i++) { // the whole frame, if no stuffing |
ea46a09a MB |
1526 | process_sample(*inptr++, &l_outptr, l_output_format, conn->fix_volume, dither, conn); |
1527 | process_sample(*inptr++, &l_outptr, l_output_format, conn->fix_volume, dither, conn); | |
c7c794c7 MB |
1528 | }; |
1529 | if (tstuff) { | |
1530 | if (tstuff == 1) { | |
1531 | // debug(3, "+++++++++"); | |
1532 | // interpolate one sample | |
ea46a09a | 1533 | process_sample(mean_32(inptr[-2], inptr[0]), &l_outptr, l_output_format, conn->fix_volume, |
d9c0028f | 1534 | dither, conn); |
ea46a09a | 1535 | process_sample(mean_32(inptr[-1], inptr[1]), &l_outptr, l_output_format, conn->fix_volume, |
d9c0028f | 1536 | dither, conn); |
c7c794c7 MB |
1537 | } else if (stuff == -1) { |
1538 | // debug(3, "---------"); | |
1539 | inptr++; | |
1540 | inptr++; | |
1541 | } | |
064bd293 MB |
1542 | |
1543 | // if you're removing, i.e. stuff < 0, copy that much less over. If you're adding, do all the | |
1544 | // rest. | |
c7c794c7 | 1545 | int remainder = length; |
064bd293 MB |
1546 | if (tstuff < 0) |
1547 | remainder = remainder + tstuff; // don't run over the correct end of the output buffer | |
c7c794c7 MB |
1548 | |
1549 | for (i = stuffsamp; i < remainder; i++) { | |
ea46a09a MB |
1550 | process_sample(*inptr++, &l_outptr, l_output_format, conn->fix_volume, dither, conn); |
1551 | process_sample(*inptr++, &l_outptr, l_output_format, conn->fix_volume, dither, conn); | |
c7c794c7 MB |
1552 | } |
1553 | } | |
d9c0028f | 1554 | conn->amountStuffed = tstuff; |
c7c794c7 MB |
1555 | return length + tstuff; |
1556 | } | |
1557 | ||
c9b3d2a2 | 1558 | #ifdef CONFIG_SOXR |
e527d9f5 MB |
1559 | // this takes an array of signed 32-bit integers and |
1560 | // (a) uses libsoxr to | |
1561 | // resample the array to have one more or one less frame, as specified in | |
1562 | // stuff, | |
1563 | // (b) multiplies each sample by the fixedvolume (a 16-bit quantity) | |
64371bb8 | 1564 | // (c) dithers the result to the output size 32/24/16/8 bits |
e527d9f5 | 1565 | // (d) outputs the result in the approprate format |
b5ee350b | 1566 | // formats accepted so far include U8, S8, S16, S24, S24_3LE, S24_3BE and S32 |
e527d9f5 | 1567 | |
2dd18416 MB |
1568 | int32_t stat_n = 0; |
1569 | double stat_mean = 0.0; | |
1570 | double stat_M2 = 0.0; | |
67e9b1b6 | 1571 | double longest_soxr_execution_time = 0.0; |
2dd18416 MB |
1572 | int64_t packets_processed = 0; |
1573 | ||
65807a8b | 1574 | int stuff_buffer_soxr_32(int32_t *inptr, int32_t *scratchBuffer, int length, |
f7717745 | 1575 | sps_format_t l_output_format, char *outptr, int stuff, int dither, |
65807a8b | 1576 | rtsp_conn_info *conn) { |
e527d9f5 MB |
1577 | if (scratchBuffer == NULL) { |
1578 | die("soxr scratchBuffer not initialised."); | |
1579 | } | |
2dd18416 | 1580 | packets_processed++; |
e527d9f5 MB |
1581 | int tstuff = stuff; |
1582 | if ((stuff > 1) || (stuff < -1) || (length < 100)) { | |
1583 | // debug(1, "Stuff argument to stuff_buffer must be from -1 to +1 and length >100."); | |
1584 | tstuff = 0; // if any of these conditions hold, don't stuff anything/ | |
1585 | } | |
1586 | ||
1587 | if (tstuff) { | |
1588 | // debug(1,"Stuff %d.",stuff); | |
65807a8b | 1589 | |
e527d9f5 MB |
1590 | soxr_io_spec_t io_spec; |
1591 | io_spec.itype = SOXR_INT32_I; | |
1592 | io_spec.otype = SOXR_INT32_I; | |
1593 | io_spec.scale = 1.0; // this seems to crash if not = 1.0 | |
1594 | io_spec.e = NULL; | |
1595 | io_spec.flags = 0; | |
1596 | ||
1597 | size_t odone; | |
1598 | ||
67e9b1b6 | 1599 | uint64_t soxr_start_time = get_absolute_time_in_ns(); |
2dd18416 | 1600 | |
65807a8b MB |
1601 | soxr_error_t error = soxr_oneshot(length, length + tstuff, 2, // Rates and # of chans. |
1602 | inptr, length, NULL, // Input. | |
1603 | scratchBuffer, length + tstuff, &odone, // Output. | |
1604 | &io_spec, // Input, output and transfer spec. | |
1605 | NULL, NULL); // Default configuration. | |
e527d9f5 MB |
1606 | |
1607 | if (error) | |
1608 | die("soxr error: %s\n", "error: %s\n", soxr_strerror(error)); | |
1609 | ||
65807a8b MB |
1610 | if (odone > (size_t)(length + 1)) |
1611 | die("odone = %u!\n", odone); | |
e527d9f5 | 1612 | |
2dd18416 MB |
1613 | // mean and variance calculations from "online_variance" algorithm at |
1614 | // https://en.wikipedia.org/wiki/Algorithms_for_calculating_variance#Online_algorithm | |
1615 | ||
54d761ff | 1616 | double soxr_execution_time = (get_absolute_time_in_ns() - soxr_start_time) * 0.000000001; |
d0917fc3 | 1617 | // debug(1,"soxr_execution_time_us: %10.1f",soxr_execution_time_us); |
67e9b1b6 MB |
1618 | if (soxr_execution_time > longest_soxr_execution_time) |
1619 | longest_soxr_execution_time = soxr_execution_time; | |
2dd18416 | 1620 | stat_n += 1; |
67e9b1b6 | 1621 | double stat_delta = soxr_execution_time - stat_mean; |
14bfba27 MB |
1622 | if (stat_n != 0) |
1623 | stat_mean += stat_delta / stat_n; | |
1624 | else | |
1625 | warn("calculation error for stat_n"); | |
67e9b1b6 | 1626 | stat_M2 += stat_delta * (soxr_execution_time - stat_mean); |
2dd18416 | 1627 | |
e527d9f5 MB |
1628 | int i; |
1629 | int32_t *ip, *op; | |
1630 | ip = inptr; | |
1631 | op = scratchBuffer; | |
1632 | ||
1633 | const int gpm = 5; | |
1634 | // keep the first (dpm) samples, to mitigate the Gibbs phenomenon | |
1635 | for (i = 0; i < gpm; i++) { | |
1636 | *op++ = *ip++; | |
1637 | *op++ = *ip++; | |
1638 | } | |
1639 | ||
1640 | // keep the last (dpm) samples, to mitigate the Gibbs phenomenon | |
7e0f6acb | 1641 | |
65807a8b MB |
1642 | // pointer arithmetic, baby -- it's da bomb. |
1643 | op = scratchBuffer + (length + tstuff - gpm) * 2; | |
1644 | ip = inptr + (length - gpm) * 2; | |
e527d9f5 MB |
1645 | for (i = 0; i < gpm; i++) { |
1646 | *op++ = *ip++; | |
65807a8b | 1647 | *op++ = *ip++; |
e527d9f5 MB |
1648 | } |
1649 | ||
1650 | // now, do the volume, dither and formatting processing | |
1651 | ip = scratchBuffer; | |
1652 | char *l_outptr = outptr; | |
1653 | for (i = 0; i < length + tstuff; i++) { | |
ea46a09a MB |
1654 | process_sample(*ip++, &l_outptr, l_output_format, conn->fix_volume, dither, conn); |
1655 | process_sample(*ip++, &l_outptr, l_output_format, conn->fix_volume, dither, conn); | |
e527d9f5 MB |
1656 | }; |
1657 | ||
1658 | } else { // the whole frame, if no stuffing | |
1659 | ||
1660 | // now, do the volume, dither and formatting processing | |
1661 | int32_t *ip = inptr; | |
1662 | char *l_outptr = outptr; | |
1663 | int i; | |
1664 | ||
1665 | for (i = 0; i < length; i++) { | |
ea46a09a MB |
1666 | process_sample(*ip++, &l_outptr, l_output_format, conn->fix_volume, dither, conn); |
1667 | process_sample(*ip++, &l_outptr, l_output_format, conn->fix_volume, dither, conn); | |
e527d9f5 MB |
1668 | }; |
1669 | } | |
2dd18416 | 1670 | |
ca8acb4a | 1671 | if (packets_processed % 1250 == 0) { |
54d761ff MB |
1672 | debug(3, |
1673 | "soxr_oneshot execution time in nanoseconds: mean, standard deviation and max " | |
1674 | "for %" PRId32 " interpolations in the last " | |
1675 | "1250 packets. %10.6f, %10.6f, %10.6f.", | |
c8b0be30 | 1676 | stat_n, stat_mean, stat_n <= 1 ? 0.0 : sqrtf(stat_M2 / (stat_n - 1)), |
67e9b1b6 | 1677 | longest_soxr_execution_time); |
2dd18416 MB |
1678 | stat_n = 0; |
1679 | stat_mean = 0.0; | |
1680 | stat_M2 = 0.0; | |
67e9b1b6 | 1681 | longest_soxr_execution_time = 0.0; |
2dd18416 MB |
1682 | } |
1683 | ||
d9c0028f | 1684 | conn->amountStuffed = tstuff; |
e527d9f5 | 1685 | return length + tstuff; |
c7c794c7 | 1686 | } |
a2fb5d21 | 1687 | #endif |
771aa1a1 | 1688 | |
58a66ebb | 1689 | void player_thread_initial_cleanup_handler(__attribute__((unused)) void *arg) { |
418b1ba7 | 1690 | rtsp_conn_info *conn = (rtsp_conn_info *)arg; |
ccc4fe09 MB |
1691 | debug(3, "Connection %d: player thread main loop exit via player_thread_initial_cleanup_handler.", |
1692 | conn->connection_number); | |
58a66ebb | 1693 | } |
d9c0028f | 1694 | |
8bee92a4 MB |
1695 | char line_of_stats[1024]; |
1696 | int statistics_row; // statistics_line 0 means print the headings; anything else 1 means print the | |
1697 | // values. Set to 0 the first time out. | |
1698 | int statistics_column; // used to index through the statistics_print_profile array to check if it | |
1699 | // should be printed | |
1700 | int was_a_previous_column; | |
1701 | int *statistics_print_profile; | |
1702 | ||
1703 | // these arrays specify which of the statistics specified by the statistics_item calls will actually | |
56bef8e7 | 1704 | // be printed -- 2 means print, 1 means print only in a debug mode, 0 means skip |
881a5ca2 | 1705 | |
60f830bc | 1706 | // clang-format off |
f06524cf MB |
1707 | int ap1_synced_statistics_print_profile[] = {2, 2, 2, 0, 2, 1, 1, 2, 1, 1, 1, 0, 1, 1, 2, 2, 1, 1}; |
1708 | int ap1_nosync_statistics_print_profile[] = {2, 0, 0, 0, 2, 1, 1, 2, 1, 1, 1, 0, 1, 1, 0, 0, 1, 0}; | |
1709 | int ap1_nodelay_statistics_print_profile[] = {0, 0, 0, 0, 2, 1, 1, 2, 0, 1, 1, 0, 1, 1, 0, 0, 1, 0}; | |
60f830bc | 1710 | |
e7098c45 MB |
1711 | int ap2_realtime_synced_stream_statistics_print_profile[] = {2, 2, 2, 0, 2, 1, 1, 2, 1, 1, 1, 0, 0, 1, 2, 2, 0, 0}; |
1712 | int ap2_realtime_nosync_stream_statistics_print_profile[] = {2, 0, 0, 0, 2, 1, 1, 2, 1, 1, 1, 0, 0, 1, 0, 0, 0, 0}; | |
1713 | int ap2_realtime_nodelay_stream_statistics_print_profile[] = {0, 0, 0, 0, 2, 1, 1, 2, 0, 1, 1, 0, 0, 1, 0, 0, 0, 0}; | |
60f830bc | 1714 | |
fd880056 | 1715 | int ap2_buffered_synced_stream_statistics_print_profile[] = {2, 2, 2, 0, 0, 0, 0, 0, 1, 1, 0, 1, 0, 0, 2, 2, 0, 0}; |
e7098c45 MB |
1716 | int ap2_buffered_nosync_stream_statistics_print_profile[] = {2, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0}; |
1717 | int ap2_buffered_nodelay_stream_statistics_print_profile[] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0}; | |
60f830bc | 1718 | // clang-format on |
8bee92a4 MB |
1719 | |
1720 | void statistics_item(const char *heading, const char *format, ...) { | |
56bef8e7 MB |
1721 | if (((statistics_print_profile[statistics_column] == 1) && (debuglev != 0)) || |
1722 | (statistics_print_profile[statistics_column] == 2)) { // include this column? | |
e4cadfc1 MB |
1723 | if (was_a_previous_column != 0) { |
1724 | if (statistics_row == 0) | |
1725 | strcat(line_of_stats, " | "); | |
1726 | else | |
1727 | strcat(line_of_stats, " "); | |
1728 | } | |
8bee92a4 MB |
1729 | if (statistics_row == 0) { |
1730 | strcat(line_of_stats, heading); | |
1731 | } else { | |
1732 | char b[1024]; | |
1733 | b[0] = 0; | |
1734 | va_list args; | |
1735 | va_start(args, format); | |
1736 | vsnprintf(b, sizeof(b), format, args); | |
1737 | va_end(args); | |
1738 | strcat(line_of_stats, b); | |
1739 | } | |
1740 | was_a_previous_column = 1; | |
1741 | } | |
1742 | statistics_column++; | |
1743 | } | |
1744 | ||
8201903a MB |
1745 | double suggested_volume(rtsp_conn_info *conn) { |
1746 | double response = config.airplay_volume; | |
72f1554c MB |
1747 | if ((conn != NULL) && (conn->own_airplay_volume_set != 0)) { |
1748 | response = conn->own_airplay_volume; | |
1749 | } else if (config.airplay_volume > config.high_threshold_airplay_volume) { | |
1750 | int64_t volume_validity_time = config.limit_to_high_volume_threshold_time_in_minutes; | |
1751 | // zero means never check the volume | |
1752 | if (volume_validity_time != 0) { | |
1753 | // If the volume is higher than the high volume threshold | |
1754 | // and enough time has gone past, suggest the default volume. | |
1755 | uint64_t time_now = get_absolute_time_in_ns(); | |
1756 | int64_t time_since_last_access_to_volume_info = | |
1757 | time_now - config.last_access_to_volume_info_time; | |
1758 | ||
1759 | volume_validity_time = volume_validity_time * 60; // to seconds | |
1760 | volume_validity_time = volume_validity_time * 1000000000; // to nanoseconds | |
1761 | ||
1762 | if ((config.airplay_volume > config.high_threshold_airplay_volume) && | |
1763 | ((config.last_access_to_volume_info_time == 0) || | |
1764 | (time_since_last_access_to_volume_info > volume_validity_time))) { | |
1765 | ||
1766 | debug(2, | |
1767 | "the current volume %.6f is higher than the high volume threshold %.6f, so the " | |
1768 | "default volume %.6f is suggested.", | |
1769 | config.airplay_volume, config.high_threshold_airplay_volume, | |
1770 | config.default_airplay_volume); | |
1771 | response = config.default_airplay_volume; | |
8201903a MB |
1772 | } |
1773 | } | |
1774 | } | |
1775 | return response; | |
1776 | } | |
1777 | ||
58a66ebb MB |
1778 | void player_thread_cleanup_handler(void *arg) { |
1779 | rtsp_conn_info *conn = (rtsp_conn_info *)arg; | |
25a13032 | 1780 | |
66163c1a | 1781 | if (config.output->stop) { |
66163c1a | 1782 | config.output->stop(); |
25a13032 MB |
1783 | } |
1784 | ||
c318796e MB |
1785 | int oldState; |
1786 | pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &oldState); | |
ccc4fe09 MB |
1787 | debug(3, "Connection %d: player thread main loop exit via player_thread_cleanup_handler.", |
1788 | conn->connection_number); | |
4addf7d2 | 1789 | |
768dc775 | 1790 | if (config.statistics_requested) { |
b4d676fe MB |
1791 | int64_t time_playing = get_absolute_time_in_ns() - conn->playstart; |
1792 | time_playing = time_playing / 1000000000; | |
1793 | int64_t elapsedHours = time_playing / 3600; | |
1794 | int64_t elapsedMin = (time_playing / 60) % 60; | |
1795 | int64_t elapsedSec = time_playing % 60; | |
99c66385 | 1796 | if (conn->frame_rate_valid) |
03d291f4 | 1797 | inform("Connection %d: Playback stopped. Total playing time %02" PRId64 ":%02" PRId64 |
95a43c9c MB |
1798 | ":%02" PRId64 ". " |
1799 | "Output: %0.2f (raw), %0.2f (corrected) " | |
953ad8ac | 1800 | "frames per second.", |
fd880056 MB |
1801 | conn->connection_number, elapsedHours, elapsedMin, elapsedSec, conn->raw_frame_rate, |
1802 | conn->corrected_frame_rate); | |
c85e7e05 | 1803 | else |
03d291f4 | 1804 | inform("Connection %d: Playback stopped. Total playing time %02" PRId64 ":%02" PRId64 |
432b56c6 MB |
1805 | ":%02" PRId64 ".", |
1806 | conn->connection_number, elapsedHours, elapsedMin, elapsedSec); | |
768dc775 MB |
1807 | } |
1808 | ||
69642bb7 | 1809 | #ifdef CONFIG_DACP_CLIENT |
c8c70b60 MB |
1810 | relinquish_dacp_server_information( |
1811 | conn); // say it doesn't belong to this conversation thread any more... | |
d3b79b96 | 1812 | #else |
72079ada | 1813 | mdns_dacp_monitor_set_id(NULL); // say we're not interested in following that DACP id any more |
3ada8c94 | 1814 | #endif |
418b1ba7 | 1815 | |
953ad8ac | 1816 | // four possibilities |
02c0a159 MB |
1817 | // 1 -- Classic Airplay -- "AirPlay 1" |
1818 | // 2 -- AirPlay 2 in Classic Airplay mode | |
953ad8ac MB |
1819 | // 3 -- AirPlay 2 in Buffered Audio Mode |
1820 | // 4 -- AirPlay 3 in Realtime Audio Mode. | |
bdfb1c6e | 1821 | |
953ad8ac MB |
1822 | #ifdef CONFIG_AIRPLAY_2 |
1823 | if (conn->airplay_type == ap_2) { | |
829ea399 | 1824 | debug(2, "Cancelling AP2 timing, control and audio threads..."); |
953ad8ac MB |
1825 | |
1826 | if (conn->airplay_stream_type == realtime_stream) { | |
04c7f845 | 1827 | debug(2, "Connection %d: Delete Realtime Audio Stream thread", conn->connection_number); |
953ad8ac MB |
1828 | pthread_cancel(conn->rtp_realtime_audio_thread); |
1829 | pthread_join(conn->rtp_realtime_audio_thread, NULL); | |
829ea399 | 1830 | |
953ad8ac | 1831 | } else if (conn->airplay_stream_type == buffered_stream) { |
829ea399 MB |
1832 | |
1833 | debug(2, "Connection %d: Delete Buffered Audio Stream thread", conn->connection_number); | |
953ad8ac MB |
1834 | pthread_cancel(conn->rtp_buffered_audio_thread); |
1835 | pthread_join(conn->rtp_buffered_audio_thread, NULL); | |
829ea399 | 1836 | |
953ad8ac MB |
1837 | } else { |
1838 | die("Unrecognised Stream Type"); | |
1839 | } | |
bdfb1c6e | 1840 | |
829ea399 MB |
1841 | debug(2, "Connection %d: Delete AirPlay 2 Control thread"); |
1842 | pthread_cancel(conn->rtp_ap2_control_thread); | |
1843 | pthread_join(conn->rtp_ap2_control_thread, NULL); | |
953ad8ac | 1844 | |
953ad8ac | 1845 | } else { |
04c7f845 | 1846 | debug(2, "Cancelling AP1-compatible timing, control and audio threads..."); |
829ea399 | 1847 | #else |
04c7f845 | 1848 | debug(2, "Cancelling AP1 timing, control and audio threads..."); |
953ad8ac | 1849 | #endif |
953ad8ac MB |
1850 | debug(3, "Cancel timing thread."); |
1851 | pthread_cancel(conn->rtp_timing_thread); | |
1852 | debug(3, "Join timing thread."); | |
1853 | pthread_join(conn->rtp_timing_thread, NULL); | |
1854 | debug(3, "Timing thread terminated."); | |
1855 | debug(3, "Cancel control thread."); | |
1856 | pthread_cancel(conn->rtp_control_thread); | |
1857 | debug(3, "Join control thread."); | |
1858 | pthread_join(conn->rtp_control_thread, NULL); | |
1859 | debug(3, "Control thread terminated."); | |
1860 | debug(3, "Cancel audio thread."); | |
1861 | pthread_cancel(conn->rtp_audio_thread); | |
1862 | debug(3, "Join audio thread."); | |
1863 | pthread_join(conn->rtp_audio_thread, NULL); | |
1864 | debug(3, "Audio thread terminated."); | |
1865 | #ifdef CONFIG_AIRPLAY_2 | |
bdfb1c6e | 1866 | } |
41f55ac1 | 1867 | // ptp_send_control_message_string("T"); // remove all timing peers to force the master to 0 |
703717a5 | 1868 | reset_anchor_info(conn); |
bdfb1c6e MB |
1869 | #endif |
1870 | ||
d3b79b96 MB |
1871 | if (conn->outbuf) { |
1872 | free(conn->outbuf); | |
1873 | conn->outbuf = NULL; | |
c8c70b60 | 1874 | } |
d3b79b96 MB |
1875 | if (conn->sbuf) { |
1876 | free(conn->sbuf); | |
1877 | conn->sbuf = NULL; | |
c8c70b60 | 1878 | } |
d3b79b96 MB |
1879 | if (conn->tbuf) { |
1880 | free(conn->tbuf); | |
1881 | conn->tbuf = NULL; | |
1882 | } | |
759b87f2 MB |
1883 | |
1884 | if (conn->statistics) { | |
ca562872 MB |
1885 | free(conn->statistics); |
1886 | conn->statistics = NULL; | |
759b87f2 | 1887 | } |
d3b79b96 | 1888 | free_audio_buffers(conn); |
5a7b7c01 MB |
1889 | if (conn->stream.type == ast_apple_lossless) |
1890 | terminate_decoders(conn); | |
418b1ba7 | 1891 | |
d3b79b96 | 1892 | conn->rtp_running = 0; |
c318796e | 1893 | pthread_setcancelstate(oldState, NULL); |
829ea399 | 1894 | debug(2, "Connection %d: player terminated.", conn->connection_number); |
c2e3fa5a | 1895 | } |
d9c0028f | 1896 | |
c2e3fa5a | 1897 | void *player_thread_func(void *arg) { |
2e442853 | 1898 | rtsp_conn_info *conn = (rtsp_conn_info *)arg; |
7c1a5fd0 | 1899 | #ifdef CONFIG_METADATA |
d6536a8e MB |
1900 | uint64_t time_of_last_metadata_progress_update = |
1901 | 0; // the assignment is to stop a compiler warning... | |
7c1a5fd0 | 1902 | #endif |
5f92164c | 1903 | uint64_t previous_frames_played = 0; // initialised to avoid a "possibly uninitialised" warning |
fd880056 MB |
1904 | uint64_t previous_raw_measurement_time = |
1905 | 0; // initialised to avoid a "possibly uninitialised" warning | |
1906 | uint64_t previous_corrected_measurement_time = | |
1907 | 0; // initialised to avoid a "possibly uninitialised" warning | |
99c66385 MB |
1908 | int previous_frames_played_valid = 0; |
1909 | ||
303a85c3 | 1910 | // pthread_cleanup_push(player_thread_initial_cleanup_handler, arg); |
deb11654 MB |
1911 | conn->latency_warning_issued = |
1912 | 0; // be permitted to generate a warning each time a play is attempted | |
418b1ba7 | 1913 | conn->packet_count = 0; |
f6b3c420 | 1914 | conn->packet_count_since_flush = 0; |
418b1ba7 | 1915 | conn->previous_random_number = 0; |
418b1ba7 MB |
1916 | conn->decoder_in_use = 0; |
1917 | conn->ab_buffering = 1; | |
1918 | conn->ab_synced = 0; | |
1919 | conn->first_packet_timestamp = 0; | |
1920 | conn->flush_requested = 0; | |
f8c24c5f | 1921 | conn->flush_output_flushed = 0; // only send a flush command to the output device once |
ca562872 MB |
1922 | conn->flush_rtp_timestamp = 0; // it seems this number has a special significance -- it seems to |
1923 | // be used as a null operand, so we'll use it like that too | |
418b1ba7 | 1924 | conn->fix_volume = 0x10000; |
c0a3dacf | 1925 | |
3f6f0932 MB |
1926 | #ifdef CONFIG_AIRPLAY_2 |
1927 | conn->ap2_flush_requested = 0; | |
1928 | conn->ap2_flush_from_valid = 0; | |
1929 | conn->ap2_rate = 0; | |
1930 | conn->ap2_play_enabled = 0; | |
1931 | #endif | |
80f15e1f | 1932 | |
41f55ac1 | 1933 | // reset_anchor_info(conn); |
418b1ba7 | 1934 | |
5a7b7c01 MB |
1935 | if (conn->stream.type == ast_apple_lossless) |
1936 | init_alac_decoder((int32_t *)&conn->stream.fmtp, | |
1937 | conn); // this sets up incoming rate, bit depth, channels. | |
1938 | // No pthread cancellation point in here | |
1939 | // This must be after init_alac_decoder | |
58a66ebb | 1940 | init_buffer(conn); // will need a corresponding deallocation. No cancellation points in here |
d4ea91aa | 1941 | ab_resync(conn); |
d90fd0df | 1942 | |
7d672bcf | 1943 | if (conn->stream.encrypted) { |
c9b3d2a2 | 1944 | #ifdef CONFIG_MBEDTLS |
7d672bcf MB |
1945 | memset(&conn->dctx, 0, sizeof(mbedtls_aes_context)); |
1946 | mbedtls_aes_setkey_dec(&conn->dctx, conn->stream.aeskey, 128); | |
1947 | #endif | |
1948 | ||
c9b3d2a2 | 1949 | #ifdef CONFIG_POLARSSL |
7d672bcf MB |
1950 | memset(&conn->dctx, 0, sizeof(aes_context)); |
1951 | aes_setkey_dec(&conn->dctx, conn->stream.aeskey, 128); | |
1952 | #endif | |
d9c0028f MB |
1953 | } |
1954 | ||
755e9590 | 1955 | conn->timestamp_epoch = 0; // indicate that the next timestamp will be the first one. |
65807a8b MB |
1956 | conn->maximum_timestamp_interval = conn->input_rate * 60; // actually there shouldn't be more than |
1957 | // about 13 seconds of a gap between | |
1958 | // successive rtptimes, at worst | |
064bd293 | 1959 | |
05305e15 | 1960 | conn->output_sample_ratio = config.output_rate / conn->input_rate; |
7b8e6865 | 1961 | |
3a6297bc | 1962 | // Sign extending rtptime calculations to 64 bit is needed from time to time. |
7b8e6865 | 1963 | |
3a6297bc MB |
1964 | // The standard rtptime is unsigned 32 bits, |
1965 | // so you can do modulo 2^32 difference calculations | |
1966 | // and get a signed result simply by typing the result as a signed 32-bit number. | |
7b8e6865 | 1967 | |
3a6297bc MB |
1968 | // So long as you can be sure the numbers are within 2^31 of each other, |
1969 | // the sign of the result calculated in this way indicates the order of the operands. | |
1970 | // For example, if you subtract a from b and the result is positive, you can conclude | |
1971 | // b is the same as or comes after a in module 2^32 order. | |
7b8e6865 | 1972 | |
3a6297bc MB |
1973 | // We want to do the same with the rtptime calculations for multiples of |
1974 | // the rtptimes (1, 2, 4 or 8 times), and we want to do this in signed 64-bit/ | |
1975 | // Therefore we need to sign extend these modulo 2^32, 2^33, 2^34, or 2^35 bit unsigned | |
1976 | // numbers on the same basis. | |
7b8e6865 | 1977 | |
3a6297bc MB |
1978 | // That is what the output_rtptime_sign_bit, output_rtptime_mask, output_rtptime_mask_not and |
1979 | // output_rtptime_sign_mask are for -- see later, calculating the sync error. | |
064bd293 | 1980 | |
5c48580d MB |
1981 | int output_rtptime_sign_bit; |
1982 | switch (conn->output_sample_ratio) { | |
7b8e6865 MB |
1983 | case 1: |
1984 | output_rtptime_sign_bit = 31; | |
1985 | break; | |
1986 | case 2: | |
1987 | output_rtptime_sign_bit = 32; | |
1988 | break; | |
1989 | case 4: | |
1990 | output_rtptime_sign_bit = 33; | |
1991 | break; | |
1992 | case 8: | |
1993 | output_rtptime_sign_bit = 34; | |
1994 | break; | |
1995 | default: | |
1996 | debug(1, "error with output ratio -- can't calculate sign bit number"); | |
1997 | output_rtptime_sign_bit = 31; | |
1998 | break; | |
5c48580d MB |
1999 | } |
2000 | ||
7b8e6865 MB |
2001 | // debug(1, "Output sample ratio is %d.", conn->output_sample_ratio); |
2002 | // debug(1, "Output output_rtptime_sign_bit: %d.", output_rtptime_sign_bit); | |
064bd293 | 2003 | |
767bed6b MB |
2004 | int64_t output_rtptime_mask = 1; |
2005 | output_rtptime_mask = output_rtptime_mask << (output_rtptime_sign_bit + 1); | |
2006 | output_rtptime_mask = output_rtptime_mask - 1; | |
7b8e6865 MB |
2007 | |
2008 | int64_t output_rtptime_mask_not = output_rtptime_mask; | |
2009 | output_rtptime_mask_not = ~output_rtptime_mask; | |
2010 | ||
2011 | int64_t output_rtptime_sign_mask = 1; | |
2012 | output_rtptime_sign_mask = output_rtptime_sign_mask << output_rtptime_sign_bit; | |
2013 | ||
2014 | conn->max_frame_size_change = | |
f94d6a5d | 2015 | 1 * conn->output_sample_ratio; // we add or subtract one frame at the nominal |
c36a7822 MB |
2016 | // rate, multiply it by the frame ratio. |
2017 | // but, on some occasions, more than one frame could be added | |
064bd293 | 2018 | |
064bd293 | 2019 | switch (config.output_format) { |
b5ee350b MB |
2020 | case SPS_FORMAT_S24_3LE: |
2021 | case SPS_FORMAT_S24_3BE: | |
05305e15 | 2022 | conn->output_bytes_per_frame = 6; |
b5ee350b | 2023 | break; |
c8b0be30 | 2024 | |
0499743b | 2025 | case SPS_FORMAT_S24: |
d91e41d9 MB |
2026 | case SPS_FORMAT_S24_LE: |
2027 | case SPS_FORMAT_S24_BE: | |
05305e15 | 2028 | conn->output_bytes_per_frame = 8; |
064bd293 | 2029 | break; |
0499743b | 2030 | case SPS_FORMAT_S32: |
d91e41d9 MB |
2031 | case SPS_FORMAT_S32_LE: |
2032 | case SPS_FORMAT_S32_BE: | |
05305e15 | 2033 | conn->output_bytes_per_frame = 8; |
064bd293 | 2034 | break; |
a53b4c5c MB |
2035 | default: |
2036 | conn->output_bytes_per_frame = 4; | |
064bd293 | 2037 | } |
d9c0028f | 2038 | |
32c7a535 | 2039 | debug(3, "Output frame bytes is %d.", conn->output_bytes_per_frame); |
e4d5570e | 2040 | |
76387f82 MB |
2041 | conn->dac_buffer_queue_minimum_length = (uint64_t)( |
2042 | config.audio_backend_buffer_interpolation_threshold_in_seconds * config.output_rate); | |
4f5ff881 | 2043 | debug(3, "dac_buffer_queue_minimum_length is %" PRIu64 " frames.", |
80f15e1f | 2044 | conn->dac_buffer_queue_minimum_length); |
7b97ea40 | 2045 | |
c9910540 | 2046 | conn->session_corrections = 0; |
05305e15 | 2047 | conn->connection_state_to_output = get_requested_connection_state_to_output(); |
87a0475c | 2048 | // this is about half a minute |
d6536a8e | 2049 | // #define trend_interval 3758 |
759b87f2 MB |
2050 | |
2051 | // this is about 8 seconds | |
c9910540 MB |
2052 | #define trend_interval 1003 |
2053 | ||
87a0475c | 2054 | int number_of_statistics, oldest_statistic, newest_statistic; |
0ca5fd3c | 2055 | int frames_seen_in_this_logging_interval = 0; |
54d761ff | 2056 | int at_least_one_frame_seen_this_session = 0; |
87a0475c MB |
2057 | int64_t tsum_of_sync_errors, tsum_of_corrections, tsum_of_insertions_and_deletions, |
2058 | tsum_of_drifts; | |
510424dc | 2059 | int64_t previous_sync_error = 0, previous_correction = 0; |
0ca5fd3c MB |
2060 | uint64_t minimum_dac_queue_size; |
2061 | int32_t minimum_buffer_occupancy; | |
2062 | int32_t maximum_buffer_occupancy; | |
d9c0028f | 2063 | |
a382ac66 | 2064 | #ifdef CONFIG_AIRPLAY_2 |
08afa822 MB |
2065 | conn->ap2_audio_buffer_minimum_size = -1; |
2066 | #endif | |
2067 | ||
56bef8e7 MB |
2068 | conn->raw_frame_rate = 0.0; |
2069 | conn->corrected_frame_rate = 0.0; | |
99c66385 | 2070 | conn->frame_rate_valid = 0; |
3888125a MB |
2071 | |
2072 | conn->input_frame_rate = 0.0; | |
51913573 | 2073 | conn->input_frame_rate_starting_point_is_valid = 0; |
0bac2fee | 2074 | |
c9910540 | 2075 | conn->buffer_occupancy = 0; |
87a0475c | 2076 | |
07e46565 | 2077 | int play_samples = 0; |
034dd53a | 2078 | uint64_t current_delay; |
771aa1a1 | 2079 | int play_number = 0; |
c9910540 | 2080 | conn->play_number_after_flush = 0; |
d9c0028f | 2081 | // int last_timestamp = 0; // for debugging only |
755e9590 | 2082 | conn->time_of_last_audio_packet = 0; |
d3148eb4 | 2083 | // conn->shutdown_requested = 0; |
771aa1a1 MB |
2084 | number_of_statistics = oldest_statistic = newest_statistic = 0; |
2085 | tsum_of_sync_errors = tsum_of_corrections = tsum_of_insertions_and_deletions = tsum_of_drifts = 0; | |
2086 | ||
2087 | const int print_interval = trend_interval; // don't ask... | |
87a0475c MB |
2088 | // I think it's useful to keep this prime to prevent it from falling into a pattern with some |
2089 | // other process. | |
2090 | ||
39e122a4 | 2091 | static char rnstate[256]; |
87a0475c MB |
2092 | initstate(time(NULL), rnstate, 256); |
2093 | ||
d3b79b96 | 2094 | signed short *inbuf; |
30a01686 | 2095 | int inbuflength; |
064bd293 | 2096 | |
e5259e87 | 2097 | unsigned int output_bit_depth = 16; // default; |
064bd293 | 2098 | |
30a01686 | 2099 | switch (config.output_format) { |
e9fef46f MB |
2100 | case SPS_FORMAT_S8: |
2101 | case SPS_FORMAT_U8: | |
2102 | output_bit_depth = 8; | |
2103 | break; | |
0499743b | 2104 | case SPS_FORMAT_S16: |
1d32976d MB |
2105 | case SPS_FORMAT_S16_LE: |
2106 | case SPS_FORMAT_S16_BE: | |
064bd293 MB |
2107 | output_bit_depth = 16; |
2108 | break; | |
0499743b | 2109 | case SPS_FORMAT_S24: |
1d32976d MB |
2110 | case SPS_FORMAT_S24_LE: |
2111 | case SPS_FORMAT_S24_BE: | |
b5ee350b MB |
2112 | case SPS_FORMAT_S24_3LE: |
2113 | case SPS_FORMAT_S24_3BE: | |
064bd293 MB |
2114 | output_bit_depth = 24; |
2115 | break; | |
0499743b | 2116 | case SPS_FORMAT_S32: |
1d32976d MB |
2117 | case SPS_FORMAT_S32_LE: |
2118 | case SPS_FORMAT_S32_BE: | |
064bd293 MB |
2119 | output_bit_depth = 32; |
2120 | break; | |
a53b4c5c MB |
2121 | case SPS_FORMAT_UNKNOWN: |
2122 | die("Unknown format choosing output bit depth"); | |
20967812 | 2123 | break; |
83c0405d MB |
2124 | case SPS_FORMAT_AUTO: |
2125 | die("Invalid format -- SPS_FORMAT_AUTO -- choosing output bit depth"); | |
2126 | break; | |
1d32976d | 2127 | case SPS_FORMAT_INVALID: |
83c0405d | 2128 | die("Invalid format -- SPS_FORMAT_INVALID -- choosing output bit depth"); |
1d32976d | 2129 | break; |
30a01686 | 2130 | } |
cb7c12d6 | 2131 | |
32c7a535 | 2132 | debug(3, "Output bit depth is %d.", output_bit_depth); |
8cabb7d0 | 2133 | |
d9c0028f | 2134 | if (conn->input_bit_depth > output_bit_depth) { |
d93aeec5 | 2135 | debug(3, "Dithering will be enabled because the input bit depth is greater than the output bit " |
8cabb7d0 | 2136 | "depth"); |
e9fef46f | 2137 | } |
4046c0e7 | 2138 | if (config.output->parameters == NULL) { |
d93aeec5 | 2139 | debug(3, "Dithering will be enabled because the output volume is being altered in software"); |
e9fef46f | 2140 | } |
064bd293 | 2141 | |
4046c0e7 MB |
2142 | if ((config.output->parameters == NULL) || (conn->input_bit_depth > output_bit_depth) || |
2143 | (config.playback_mode == ST_mono)) | |
2144 | conn->enable_dither = 1; | |
2145 | ||
c5ff0dfe | 2146 | // remember, the output device may never have been initialised prior to this call |
4046c0e7 MB |
2147 | config.output->start(config.output_rate, config.output_format); // will need a corresponding stop |
2148 | ||
64371bb8 | 2149 | // we need an intermediate "transition" buffer |
d9c0028f | 2150 | |
54d761ff MB |
2151 | conn->tbuf = malloc( |
2152 | sizeof(int32_t) * 2 * | |
2153 | (conn->max_frames_per_packet * conn->output_sample_ratio + conn->max_frame_size_change)); | |
d3b79b96 | 2154 | if (conn->tbuf == NULL) |
d9c0028f | 2155 | die("Failed to allocate memory for the transition buffer."); |
65807a8b | 2156 | |
6dc30c6c | 2157 | // initialise this, because soxr stuffing might be chosen later |
6d66b2ed | 2158 | |
54d761ff MB |
2159 | conn->sbuf = malloc( |
2160 | sizeof(int32_t) * 2 * | |
2161 | (conn->max_frames_per_packet * conn->output_sample_ratio + conn->max_frame_size_change)); | |
d3b79b96 MB |
2162 | if (conn->sbuf == NULL) |
2163 | die("Failed to allocate memory for the sbuf buffer."); | |
6d66b2ed | 2164 | |
064bd293 MB |
2165 | // The size of these dependents on the number of frames, the size of each frame and the maximum |
2166 | // size change | |
d3b79b96 | 2167 | conn->outbuf = malloc( |
d9c0028f MB |
2168 | conn->output_bytes_per_frame * |
2169 | (conn->max_frames_per_packet * conn->output_sample_ratio + conn->max_frame_size_change)); | |
d3b79b96 | 2170 | if (conn->outbuf == NULL) |
64371bb8 | 2171 | die("Failed to allocate memory for an output buffer."); |
755e9590 | 2172 | conn->first_packet_timestamp = 0; |
c8741423 | 2173 | conn->missing_packets = conn->late_packets = conn->too_late_packets = conn->resend_requests = 0; |
064bd293 MB |
2174 | int sync_error_out_of_bounds = |
2175 | 0; // number of times in a row that there's been a serious sync error | |
d343a851 | 2176 | |
ca562872 | 2177 | conn->statistics = malloc(sizeof(stats_t) * trend_interval); |
759b87f2 | 2178 | if (conn->statistics == NULL) |
ca562872 | 2179 | die("Failed to allocate a statistics buffer"); |
759b87f2 | 2180 | |
c9910540 MB |
2181 | conn->framesProcessedInThisEpoch = 0; |
2182 | conn->framesGeneratedInThisEpoch = 0; | |
2183 | conn->correctionsRequestedInThisEpoch = 0; | |
8bee92a4 MB |
2184 | statistics_row = 0; // statistics_line 0 means print the headings; anything else 1 means print the |
2185 | // values. Set to 0 the first time out. | |
27895723 MB |
2186 | |
2187 | // decide on what statistics profile to use, if requested | |
8bee92a4 | 2188 | #ifdef CONFIG_AIRPLAY_2 |
27895723 MB |
2189 | if (conn->airplay_type == ap_2) { |
2190 | if (conn->airplay_stream_type == realtime_stream) { | |
432b56c6 | 2191 | if (config.output->delay) { |
27895723 MB |
2192 | if (config.no_sync == 0) |
2193 | statistics_print_profile = ap2_realtime_synced_stream_statistics_print_profile; | |
2194 | else | |
2195 | statistics_print_profile = ap2_realtime_nosync_stream_statistics_print_profile; | |
78f5153b | 2196 | } else { |
27895723 | 2197 | statistics_print_profile = ap2_realtime_nodelay_stream_statistics_print_profile; |
78f5153b JK |
2198 | } |
2199 | } else { | |
432b56c6 | 2200 | if (config.output->delay) { |
8bee92a4 | 2201 | if (config.no_sync == 0) |
27895723 | 2202 | statistics_print_profile = ap2_buffered_synced_stream_statistics_print_profile; |
8bee92a4 | 2203 | else |
27895723 | 2204 | statistics_print_profile = ap2_buffered_nosync_stream_statistics_print_profile; |
8bee92a4 | 2205 | } else { |
27895723 | 2206 | statistics_print_profile = ap2_buffered_nodelay_stream_statistics_print_profile; |
8bee92a4 | 2207 | } |
78f5153b | 2208 | } |
27895723 | 2209 | } else { |
8bee92a4 | 2210 | #endif |
432b56c6 | 2211 | if (config.output->delay) { |
27895723 MB |
2212 | if (config.no_sync == 0) |
2213 | statistics_print_profile = ap1_synced_statistics_print_profile; | |
2214 | else | |
2215 | statistics_print_profile = ap1_nosync_statistics_print_profile; | |
2216 | } else { | |
2217 | statistics_print_profile = ap1_nodelay_statistics_print_profile; | |
2218 | } | |
2219 | // airplay 1 stuff here | |
2220 | #ifdef CONFIG_AIRPLAY_2 | |
78f5153b | 2221 | } |
27895723 MB |
2222 | #endif |
2223 | ||
c2940eb2 MB |
2224 | #ifdef CONFIG_AIRPLAY_2 |
2225 | if (conn->timing_type == ts_ntp) { | |
2226 | #endif | |
2227 | ||
6a130621 MB |
2228 | // create and start the timing, control and audio receiver threads |
2229 | pthread_create(&conn->rtp_audio_thread, NULL, &rtp_audio_receiver, (void *)conn); | |
2230 | pthread_create(&conn->rtp_control_thread, NULL, &rtp_control_receiver, (void *)conn); | |
2231 | pthread_create(&conn->rtp_timing_thread, NULL, &rtp_timing_receiver, (void *)conn); | |
c2940eb2 MB |
2232 | |
2233 | #ifdef CONFIG_AIRPLAY_2 | |
2234 | } | |
bdfb1c6e | 2235 | #endif |
c8c70b60 | 2236 | |
d3b79b96 MB |
2237 | pthread_cleanup_push(player_thread_cleanup_handler, arg); // undo what's been done so far |
2238 | ||
a5c65cec MB |
2239 | // stop looking elsewhere for DACP stuff |
2240 | int oldState; | |
2241 | pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &oldState); | |
6e6c8213 | 2242 | |
ec7d46bc | 2243 | #ifdef CONFIG_DACP_CLIENT |
72079ada | 2244 | set_dacp_server_information(conn); |
ec7d46bc | 2245 | #else |
72079ada | 2246 | mdns_dacp_monitor_set_id(conn->dacp_id); |
ec7d46bc | 2247 | #endif |
72079ada | 2248 | |
a5c65cec | 2249 | pthread_setcancelstate(oldState, NULL); |
2986b282 | 2250 | |
8201903a MB |
2251 | // if not already set, set the volume to the pending_airplay_volume, if any, or otherwise to the |
2252 | // suggested volume. | |
2253 | ||
2254 | double initial_volume = suggested_volume(conn); | |
2255 | debug(2, "Set initial volume to %.6f.", initial_volume); | |
c645a039 | 2256 | player_volume(initial_volume, conn); // will contain a cancellation point if asked to wait |
58a66ebb | 2257 | |
45c1c566 | 2258 | debug(2, "Play begin"); |
227f8ce4 | 2259 | while (1) { |
02c0a159 | 2260 | #ifdef CONFIG_METADATA |
40446668 | 2261 | int this_is_the_first_frame = 0; // will be set if it is |
02c0a159 | 2262 | #endif |
14bfba27 MB |
2263 | // check a few parameters to ensure they are non-zero |
2264 | if (config.output_rate == 0) | |
2265 | debug(1, "config.output_rate is zero!"); | |
2266 | if (conn->output_sample_ratio == 0) | |
2267 | debug(1, "conn->output_sample_ratio is zero!"); | |
2268 | if (conn->input_rate == 0) | |
2269 | debug(1, "conn->input_rate is zero!"); | |
2270 | if (conn->input_bytes_per_frame == 0) | |
2271 | debug(1, "conn->input_bytes_per_frame is zero!"); | |
2272 | ||
ccc4fe09 MB |
2273 | pthread_testcancel(); // allow a pthread_cancel request to take effect. |
2274 | abuf_t *inframe = buffer_get_frame(conn); // this has cancellation point(s), but it's not | |
b9cf91b2 | 2275 | // guaranteed that they'll always be executed |
99c66385 | 2276 | uint64_t local_time_now = get_absolute_time_in_ns(); // types okay |
8201903a MB |
2277 | config.last_access_to_volume_info_time = |
2278 | local_time_now; // ensure volume info remains seen as valid | |
2279 | ||
7187b63e | 2280 | if (inframe) { |
945483d9 | 2281 | inbuf = inframe->data; |
30a01686 | 2282 | inbuflength = inframe->length; |
945483d9 | 2283 | if (inbuf) { |
b4d676fe MB |
2284 | if (play_number == 0) |
2285 | conn->playstart = get_absolute_time_in_ns(); | |
0462ead3 | 2286 | play_number++; |
e76a6366 MB |
2287 | // if (play_number % 100 == 0) |
2288 | // debug(3, "Play frame %d.", play_number); | |
c9910540 | 2289 | conn->play_number_after_flush++; |
de071aef | 2290 | if (inframe->given_timestamp == 0) { |
919e4d6a | 2291 | debug(2, |
54d761ff MB |
2292 | "Player has supplied a silent frame, (possibly frame %u) for play number %d, " |
2293 | "status 0x%X after %u resend requests.", | |
bdfb1c6e | 2294 | conn->last_seqno_read + 1, play_number, inframe->status, |
54d761ff | 2295 | inframe->resend_request_number); |
ca562872 | 2296 | conn->last_seqno_read = |
bdfb1c6e | 2297 | ((conn->last_seqno_read + 1) & 0xffff); // manage the packet out of sequence minder |
6d66b2ed MB |
2298 | |
2299 | void *silence = malloc(conn->output_bytes_per_frame * conn->max_frames_per_packet * | |
2300 | conn->output_sample_ratio); | |
2301 | if (silence == NULL) { | |
2302 | debug(1, "Failed to allocate memory for a silent frame silence buffer."); | |
2303 | } else { | |
2304 | // the player may change the contents of the buffer, so it has to be zeroed each time; | |
b9cf91b2 | 2305 | // might as well malloc and free it locally |
4046c0e7 MB |
2306 | conn->previous_random_number = generate_zero_frames( |
2307 | silence, conn->max_frames_per_packet * conn->output_sample_ratio, | |
2308 | config.output_format, conn->enable_dither, conn->previous_random_number); | |
fd880056 MB |
2309 | config.output->play(silence, conn->max_frames_per_packet * conn->output_sample_ratio, |
2310 | play_samples_are_untimed, 0, 0); | |
6d66b2ed MB |
2311 | free(silence); |
2312 | } | |
c9910540 MB |
2313 | } else if (conn->play_number_after_flush < 10) { |
2314 | /* | |
2315 | int64_t difference = 0; | |
2316 | if (last_timestamp) | |
2317 | difference = inframe->timestamp - last_timestamp; | |
2318 | last_timestamp = inframe->timestamp; | |
d9c0028f MB |
2319 | debug(1, "Play number %d, monotonic timestamp %llx, difference |
2320 | %lld.",conn->play_number_after_flush,inframe->timestamp,difference); | |
c9910540 | 2321 | */ |
6d66b2ed MB |
2322 | void *silence = malloc(conn->output_bytes_per_frame * conn->max_frames_per_packet * |
2323 | conn->output_sample_ratio); | |
2324 | if (silence == NULL) { | |
2325 | debug(1, "Failed to allocate memory for a flush silence buffer."); | |
2326 | } else { | |
2327 | // the player may change the contents of the buffer, so it has to be zeroed each time; | |
b9cf91b2 | 2328 | // might as well malloc and free it locally |
4046c0e7 MB |
2329 | conn->previous_random_number = generate_zero_frames( |
2330 | silence, conn->max_frames_per_packet * conn->output_sample_ratio, | |
2331 | config.output_format, conn->enable_dither, conn->previous_random_number); | |
fd880056 MB |
2332 | config.output->play(silence, conn->max_frames_per_packet * conn->output_sample_ratio, |
2333 | play_samples_are_untimed, 0, 0); | |
6d66b2ed MB |
2334 | free(silence); |
2335 | } | |
771aa1a1 | 2336 | } else { |
4046c0e7 | 2337 | |
2ca6e42b MB |
2338 | if (((config.output->parameters == NULL) && (config.ignore_volume_control == 0) && |
2339 | (config.airplay_volume != 0.0)) || | |
2340 | (conn->input_bit_depth > output_bit_depth) || (config.playback_mode == ST_mono)) | |
4046c0e7 MB |
2341 | conn->enable_dither = 1; |
2342 | else | |
2343 | conn->enable_dither = 0; | |
064bd293 | 2344 | |
30a01686 | 2345 | // here, let's transform the frame of data, if necessary |
064bd293 | 2346 | |
68456567 | 2347 | switch (conn->input_bit_depth) { |
d9c0028f MB |
2348 | case 16: { |
2349 | int i, j; | |
2350 | int16_t ls, rs; | |
07e46565 | 2351 | int32_t ll = 0, rl = 0; |
d9c0028f | 2352 | int16_t *inps = inbuf; |
07e46565 | 2353 | // int16_t *outps = tbuf; |
d3b79b96 | 2354 | int32_t *outpl = (int32_t *)conn->tbuf; |
d9c0028f MB |
2355 | for (i = 0; i < inbuflength; i++) { |
2356 | ls = *inps++; | |
2357 | rs = *inps++; | |
2358 | ||
2359 | // here, do the mode stuff -- mono / reverse stereo / leftonly / rightonly | |
2360 | // also, raise the 16-bit samples to 32 bits. | |
2361 | ||
2362 | switch (config.playback_mode) { | |
2363 | case ST_mono: { | |
2ab4895f MB |
2364 | int32_t lsl = ls; |
2365 | int32_t rsl = rs; | |
2366 | int32_t both = lsl + rsl; | |
d9c0028f MB |
2367 | both = both << (16 - 1); // keep all 17 bits of the sum of the 16bit left and right |
2368 | // -- the 17th bit will influence dithering later | |
2369 | ll = both; | |
2370 | rl = both; | |
2371 | } break; | |
2372 | case ST_reverse_stereo: { | |
2373 | ll = rs; | |
2374 | rl = ls; | |
2375 | ll = ll << 16; | |
2376 | rl = rl << 16; | |
2377 | } break; | |
2378 | case ST_left_only: | |
2379 | rl = ls; | |
2380 | ll = ls; | |
2381 | ll = ll << 16; | |
2382 | rl = rl << 16; | |
2383 | break; | |
2384 | case ST_right_only: | |
2385 | ll = rs; | |
2386 | rl = rs; | |
2387 | ll = ll << 16; | |
2388 | rl = rl << 16; | |
2389 | break; | |
2390 | case ST_stereo: | |
2391 | ll = ls; | |
2392 | rl = rs; | |
2393 | ll = ll << 16; | |
2394 | rl = rl << 16; | |
2395 | break; // nothing extra to do | |
2396 | } | |
30a01686 | 2397 | |
d9c0028f | 2398 | // here, replicate the samples if you're upsampling |
064bd293 | 2399 | |
d9c0028f MB |
2400 | for (j = 0; j < conn->output_sample_ratio; j++) { |
2401 | *outpl++ = ll; | |
2402 | *outpl++ = rl; | |
064bd293 | 2403 | } |
d9c0028f | 2404 | } |
d4ea91aa MB |
2405 | } break; |
2406 | case 32: { | |
2407 | int i, j; | |
2408 | int32_t ls, rs; | |
2409 | int32_t ll = 0, rl = 0; | |
c5dafbd2 | 2410 | int32_t *inps = (int32_t *)inbuf; |
d4ea91aa MB |
2411 | int32_t *outpl = (int32_t *)conn->tbuf; |
2412 | for (i = 0; i < inbuflength; i++) { | |
2413 | ls = *inps++; | |
2414 | rs = *inps++; | |
2415 | ||
2416 | // here, do the mode stuff -- mono / reverse stereo / leftonly / rightonly | |
2417 | ||
2418 | switch (config.playback_mode) { | |
2419 | case ST_mono: { | |
69112127 MB |
2420 | int64_t lsl = ls; |
2421 | int64_t rsl = rs; | |
2422 | int64_t both = lsl + rsl; | |
d4ea91aa MB |
2423 | both = both >> 1; |
2424 | uint32_t both32 = both; | |
2425 | ll = both32; | |
2426 | rl = both32; | |
2427 | } break; | |
2428 | case ST_reverse_stereo: { | |
2429 | ll = rs; | |
2430 | rl = ls; | |
2431 | } break; | |
2432 | case ST_left_only: | |
2433 | rl = ls; | |
2434 | ll = ls; | |
2435 | break; | |
2436 | case ST_right_only: | |
2437 | ll = rs; | |
2438 | rl = rs; | |
2439 | break; | |
2440 | case ST_stereo: | |
2441 | ll = ls; | |
2442 | rl = rs; | |
2443 | break; // nothing extra to do | |
2444 | } | |
064bd293 | 2445 | |
d4ea91aa MB |
2446 | // here, replicate the samples if you're upsampling |
2447 | ||
2448 | for (j = 0; j < conn->output_sample_ratio; j++) { | |
2449 | *outpl++ = ll; | |
2450 | *outpl++ = rl; | |
2451 | } | |
2452 | } | |
d9c0028f | 2453 | } break; |
d4ea91aa | 2454 | |
d9c0028f | 2455 | default: |
d4ea91aa | 2456 | die("Shairport Sync only supports 16 or 32 bit input"); |
30a01686 | 2457 | } |
064bd293 | 2458 | |
a8caa0f9 | 2459 | inbuflength *= conn->output_sample_ratio; |
64371bb8 | 2460 | |
87a0475c MB |
2461 | // We have a frame of data. We need to see if we want to add or remove a frame from it to |
2462 | // keep in sync. | |
771aa1a1 MB |
2463 | // So we calculate the timing error for the first frame in the DAC. |
2464 | // If it's ahead of time, we add one audio frame to this frame to delay a subsequent frame | |
87a0475c MB |
2465 | // If it's late, we remove an audio frame from this frame to bring a subsequent frame |
2466 | // forward in time | |
2467 | ||
e76a6366 MB |
2468 | // now, go back as far as the total latency less, say, 100 ms, and check the presence of |
2469 | // frames from then onwards | |
2470 | ||
0ca5fd3c | 2471 | frames_seen_in_this_logging_interval++; |
87a0475c | 2472 | |
c887aafd | 2473 | // This is the timing error for the next audio frame in the DAC, if applicable |
87a0475c MB |
2474 | int64_t sync_error = 0; |
2475 | ||
c887aafd | 2476 | int amount_to_stuff = 0; |
87a0475c | 2477 | |
0b7e9541 | 2478 | // check sequencing |
f06e638d MB |
2479 | if (conn->last_seqno_read == -1) |
2480 | conn->last_seqno_read = | |
064bd293 | 2481 | inframe->sequence_number; // int32_t from seq_t, i.e. uint16_t, so okay. |
0b7e9541 | 2482 | else { |
f06e638d | 2483 | conn->last_seqno_read = |
bdfb1c6e | 2484 | (conn->last_seqno_read + 1) & 0xffff; // int32_t from seq_t, i.e. uint16_t, so okay. |
064bd293 | 2485 | if (inframe->sequence_number != |
f06e638d | 2486 | conn->last_seqno_read) { // seq_t, ei.e. uint16_t and int32_t, so okay |
54d761ff MB |
2487 | debug(2, |
2488 | "Player: packets out of sequence: expected: %u, got: %u, with ab_read: %u " | |
2489 | "and ab_write: %u.", | |
5c48bfe0 | 2490 | conn->last_seqno_read, inframe->sequence_number, conn->ab_read, conn->ab_write); |
f06e638d | 2491 | conn->last_seqno_read = inframe->sequence_number; // reset warning... |
c887aafd | 2492 | } |
0b7e9541 | 2493 | } |
c887aafd | 2494 | |
0ac00359 | 2495 | int16_t bo = conn->ab_write - conn->ab_read; // do this in 16 bits |
7b8e6865 | 2496 | conn->buffer_occupancy = bo; // 32 bits |
e810eb64 | 2497 | |
0ca5fd3c MB |
2498 | if ((frames_seen_in_this_logging_interval == 1) || |
2499 | (conn->buffer_occupancy < minimum_buffer_occupancy)) | |
c9910540 | 2500 | minimum_buffer_occupancy = conn->buffer_occupancy; |
e810eb64 | 2501 | |
0ca5fd3c MB |
2502 | if ((frames_seen_in_this_logging_interval == 1) || |
2503 | (conn->buffer_occupancy > maximum_buffer_occupancy)) | |
c9910540 | 2504 | maximum_buffer_occupancy = conn->buffer_occupancy; |
14bfba27 | 2505 | |
5f8e6e39 | 2506 | // now, before outputting anything to the output device, check the stats |
5f8e6e39 | 2507 | |
14bfba27 MB |
2508 | if (play_number % print_interval == 0) { |
2509 | ||
2510 | // here, calculate the input and output frame rates, where possible, even if statistics | |
2511 | // have not been requested | |
2512 | // this is to calculate them in case they are needed by the D-Bus interface or | |
2513 | // elsewhere. | |
2514 | ||
2515 | if (conn->input_frame_rate_starting_point_is_valid) { | |
2516 | uint64_t elapsed_reception_time, frames_received; | |
2517 | elapsed_reception_time = | |
2518 | conn->frames_inward_measurement_time - conn->frames_inward_measurement_start_time; | |
2519 | frames_received = conn->frames_inward_frames_received_at_measurement_time - | |
2520 | conn->frames_inward_frames_received_at_measurement_start_time; | |
2521 | conn->input_frame_rate = | |
2522 | (1.0E9 * frames_received) / | |
2523 | elapsed_reception_time; // an IEEE double calculation with two 64-bit integers | |
2524 | } else { | |
2525 | conn->input_frame_rate = 0.0; | |
5f8e6e39 MB |
2526 | } |
2527 | ||
b9d3abfa | 2528 | int stats_status = 0; |
14bfba27 MB |
2529 | if ((config.output->delay) && (config.no_sync == 0) && (config.output->stats)) { |
2530 | uint64_t frames_sent_for_play; | |
56bef8e7 MB |
2531 | uint64_t raw_measurement_time; |
2532 | uint64_t corrected_measurement_time; | |
14bfba27 MB |
2533 | uint64_t actual_delay; |
2534 | stats_status = | |
56bef8e7 MB |
2535 | config.output->stats(&raw_measurement_time, &corrected_measurement_time, |
2536 | &actual_delay, &frames_sent_for_play); | |
dc5b8f1a MB |
2537 | // debug(1,"status: %d, actual_delay: %" PRIu64 ", frames_sent_for_play: %" PRIu64 ", |
2538 | // frames_played: %" PRIu64 ".", stats_status, actual_delay, frames_sent_for_play, | |
2539 | // frames_sent_for_play - actual_delay); | |
14bfba27 MB |
2540 | uint64_t frames_played = frames_sent_for_play - actual_delay; |
2541 | // If the status is zero, it means that there were no output problems since the | |
2542 | // last time the stats call was made. Thus, the frame rate should be valid. | |
b9d3abfa | 2543 | if ((stats_status == 0) && (previous_frames_played_valid != 0)) { |
14bfba27 | 2544 | uint64_t frames_played_in_this_interval = frames_played - previous_frames_played; |
56bef8e7 MB |
2545 | int64_t raw_interval = raw_measurement_time - previous_raw_measurement_time; |
2546 | int64_t corrected_interval = | |
2547 | corrected_measurement_time - previous_corrected_measurement_time; | |
2548 | if (raw_interval != 0) { | |
2549 | conn->raw_frame_rate = (1e9 * frames_played_in_this_interval) / raw_interval; | |
2550 | conn->corrected_frame_rate = | |
2551 | (1e9 * frames_played_in_this_interval) / corrected_interval; | |
14bfba27 | 2552 | conn->frame_rate_valid = 1; |
dc5b8f1a MB |
2553 | // debug(1,"frames_played_in_this_interval: %" PRIu64 ", interval: %" PRId64 ", |
2554 | // rate: %f.", | |
7890188d | 2555 | // frames_played_in_this_interval, interval, conn->frame_rate); |
14bfba27 MB |
2556 | } |
2557 | } | |
2558 | ||
2559 | // uncomment the if statement if your want to get as long a period for | |
2560 | // calculating the frame rate as possible without an output break or error | |
87d887f4 MB |
2561 | if ((stats_status != 0) || (previous_frames_played_valid == 0)) { |
2562 | // if we have just detected an outputting error, or if we have no | |
2563 | // starting information | |
2564 | if (stats_status != 0) | |
2565 | conn->frame_rate_valid = 0; | |
2566 | previous_frames_played = frames_played; | |
56bef8e7 MB |
2567 | previous_raw_measurement_time = raw_measurement_time; |
2568 | previous_corrected_measurement_time = corrected_measurement_time; | |
87d887f4 MB |
2569 | previous_frames_played_valid = 1; |
2570 | } | |
14bfba27 | 2571 | } |
5f8e6e39 | 2572 | |
14bfba27 MB |
2573 | // we can now calculate running averages for sync error (frames), corrections (ppm), |
2574 | // insertions plus deletions (ppm), drift (ppm) | |
2575 | double moving_average_sync_error = 0.0; | |
2576 | double moving_average_correction = 0.0; | |
2577 | double moving_average_insertions_plus_deletions = 0.0; | |
2578 | if (number_of_statistics == 0) { | |
f6127827 | 2579 | debug(2, "number_of_statistics is zero!"); |
5f8e6e39 | 2580 | } else { |
14bfba27 MB |
2581 | moving_average_sync_error = (1.0 * tsum_of_sync_errors) / number_of_statistics; |
2582 | moving_average_correction = (1.0 * tsum_of_corrections) / number_of_statistics; | |
2583 | moving_average_insertions_plus_deletions = | |
2584 | (1.0 * tsum_of_insertions_and_deletions) / number_of_statistics; | |
2585 | // double moving_average_drift = (1.0 * tsum_of_drifts) / number_of_statistics; | |
5f8e6e39 | 2586 | } |
14bfba27 MB |
2587 | // if ((play_number/print_interval)%20==0) |
2588 | // figure out which statistics profile to use, depending on the kind of stream | |
2589 | ||
2590 | if (config.statistics_requested) { | |
2591 | ||
0ca5fd3c | 2592 | if (frames_seen_in_this_logging_interval) { |
14bfba27 MB |
2593 | do { |
2594 | line_of_stats[0] = '\0'; | |
2595 | statistics_column = 0; | |
2596 | was_a_previous_column = 0; | |
1115ec4f | 2597 | statistics_item("Sync Error ms", "%*.2f", 13, |
14bfba27 | 2598 | 1000 * moving_average_sync_error / config.output_rate); |
1115ec4f | 2599 | statistics_item("Net Sync PPM", "%*.1f", 12, |
14bfba27 MB |
2600 | moving_average_correction * 1000000 / |
2601 | (352 * conn->output_sample_ratio)); | |
1115ec4f | 2602 | statistics_item("All Sync PPM", "%*.1f", 12, |
14bfba27 MB |
2603 | moving_average_insertions_plus_deletions * 1000000 / |
2604 | (352 * conn->output_sample_ratio)); | |
1115ec4f MB |
2605 | statistics_item(" Packets", "%*d", 11, play_number); |
2606 | statistics_item("Missing", "%*" PRIu64 "", 7, conn->missing_packets); | |
2607 | statistics_item(" Late", "%*" PRIu64 "", 6, conn->late_packets); | |
2608 | statistics_item("Too Late", "%*" PRIu64 "", 8, conn->too_late_packets); | |
2609 | statistics_item("Resend Reqs", "%*" PRIu64 "", 11, conn->resend_requests); | |
2610 | statistics_item("Min DAC Queue", "%*" PRIu64 "", 13, minimum_dac_queue_size); | |
2611 | statistics_item("Min Buffers", "%*" PRIu32 "", 11, minimum_buffer_occupancy); | |
2612 | statistics_item("Max Buffers", "%*" PRIu32 "", 11, maximum_buffer_occupancy); | |
a382ac66 MB |
2613 | #ifdef CONFIG_AIRPLAY_2 |
2614 | if (conn->ap2_audio_buffer_minimum_size > 10 * 1024) | |
1115ec4f | 2615 | statistics_item("Min Buffer Size", "%*" PRIu32 "k", 14, |
a382ac66 | 2616 | conn->ap2_audio_buffer_minimum_size / 1024); |
08afa822 | 2617 | else |
1115ec4f | 2618 | statistics_item("Min Buffer Size", "%*" PRIu32 "", 15, |
a382ac66 | 2619 | conn->ap2_audio_buffer_minimum_size); |
f06524cf | 2620 | #else |
1d228870 | 2621 | statistics_item("N/A", " "); // dummy -- should never be visible |
08afa822 | 2622 | #endif |
1115ec4f MB |
2623 | statistics_item("Nominal FPS", "%*.2f", 11, conn->remote_frame_rate); |
2624 | statistics_item("Received FPS", "%*.2f", 12, conn->input_frame_rate); | |
fd880056 MB |
2625 | // only make the next two columns appear if we are getting stats information from |
2626 | // the back end | |
0df6e18b MB |
2627 | if (config.output->stats) { |
2628 | if (conn->frame_rate_valid) { | |
2629 | statistics_item("Output FPS (r)", "%*.2f", 14, conn->raw_frame_rate); | |
2630 | statistics_item("Output FPS (c)", "%*.2f", 14, conn->corrected_frame_rate); | |
2631 | } else { | |
2632 | statistics_item("Output FPS (r)", " N/A"); | |
2633 | statistics_item("Output FPS (c)", " N/A"); | |
2634 | } | |
56bef8e7 | 2635 | } else { |
0df6e18b | 2636 | statistics_column = statistics_column + 2; |
56bef8e7 | 2637 | } |
1115ec4f | 2638 | statistics_item("Source Drift PPM", "%*.2f", 16, |
14bfba27 | 2639 | (conn->local_to_remote_time_gradient - 1.0) * 1000000); |
1115ec4f | 2640 | statistics_item("Drift Samples", "%*d", 13, |
14bfba27 | 2641 | conn->local_to_remote_time_gradient_sample_count); |
56bef8e7 | 2642 | /* |
14bfba27 MB |
2643 | statistics_item("estimated (unused) correction ppm", "%*.2f", |
2644 | strlen("estimated (unused) correction ppm"), | |
2645 | (conn->frame_rate_valid != 0) | |
2646 | ? ((conn->frame_rate - | |
2647 | conn->remote_frame_rate * conn->output_sample_ratio * | |
2648 | conn->local_to_remote_time_gradient) * | |
2649 | 1000000) / | |
2650 | conn->frame_rate | |
2651 | : 0.0); | |
56bef8e7 | 2652 | */ |
14bfba27 MB |
2653 | statistics_row++; |
2654 | inform(line_of_stats); | |
2655 | } while (statistics_row < 2); | |
2656 | } else { | |
2657 | inform("No frames received in the last sampling interval."); | |
2658 | } | |
2659 | } | |
a382ac66 | 2660 | #ifdef CONFIG_AIRPLAY_2 |
08afa822 MB |
2661 | conn->ap2_audio_buffer_minimum_size = -1; |
2662 | #endif | |
5f8e6e39 | 2663 | } |
e810eb64 | 2664 | |
adc44b25 MB |
2665 | // here, we want to check (a) if we are meant to do synchronisation, |
2666 | // (b) if we have a delay procedure, (c) if we can get the delay. | |
2667 | ||
cca403c2 MB |
2668 | // If any of these are false, we don't do any synchronisation stuff |
2669 | ||
064bd293 | 2670 | int resp = -1; // use this as a flag -- if negative, we can't rely on a real known delay |
bdfb1c6e | 2671 | current_delay = -1; // use this as a failure flag |
064bd293 MB |
2672 | |
2673 | if (config.output->delay) { | |
2674 | long l_delay; | |
2675 | resp = config.output->delay(&l_delay); | |
064bd293 | 2676 | if (resp == 0) { // no error |
6f8b35d1 | 2677 | current_delay = l_delay; |
034dd53a | 2678 | if (l_delay >= 0) |
ca562872 | 2679 | current_delay = l_delay; |
034dd53a MB |
2680 | else { |
2681 | debug(2, "Underrun of %ld frames reported, but ignored.", l_delay); | |
064bd293 MB |
2682 | current_delay = |
2683 | 0; // could get a negative value if there was underrun, but ignore it. | |
2684 | } | |
0ca5fd3c MB |
2685 | if ((frames_seen_in_this_logging_interval == 1) || |
2686 | (current_delay < minimum_dac_queue_size)) { | |
064bd293 MB |
2687 | minimum_dac_queue_size = current_delay; // update for display later |
2688 | } | |
2689 | } else { | |
6f8b35d1 MB |
2690 | current_delay = 0; |
2691 | if ((resp == sps_extra_code_output_stalled) && | |
d6536a8e MB |
2692 | (config.unfixable_error_reported == 0)) { |
2693 | config.unfixable_error_reported = 1; | |
9d5ff22f MB |
2694 | if (config.cmd_unfixable) { |
2695 | warn("Connection %d: An unfixable error has been detected -- output device is " | |
2696 | "stalled. Executing the " | |
2697 | "\"run_this_if_an_unfixable_error_is_detected\" command.", | |
2698 | conn->connection_number); | |
44830377 | 2699 | command_execute(config.cmd_unfixable, "output_device_stalled", 1); |
9d5ff22f MB |
2700 | } else { |
2701 | warn("Connection %d: An unfixable error has been detected -- output device is " | |
2702 | "stalled. \"No " | |
2703 | "run_this_if_an_unfixable_error_is_detected\" command provided -- nothing " | |
2704 | "done.", | |
2705 | conn->connection_number); | |
2706 | } | |
129343c1 | 2707 | } else { |
d2ca8c84 MB |
2708 | if ((resp != -EBUSY) && |
2709 | (resp != -ENODEV)) // delay and not-there errors can be reported if the device | |
2710 | // is (hopefully temporarily) busy or unavailable | |
129343c1 MB |
2711 | debug(1, "Delay error %d when checking running latency.", resp); |
2712 | } | |
064bd293 MB |
2713 | } |
2714 | } | |
0a9e4c8e | 2715 | |
6f8b35d1 | 2716 | if (resp == 0) { |
87a0475c | 2717 | |
d2dba7cd | 2718 | uint32_t should_be_frame_32; |
5c48580d | 2719 | // this is denominated in the frame rate of the incoming stream |
d2dba7cd | 2720 | local_time_to_frame(local_time_now, &should_be_frame_32, conn); |
44c61835 | 2721 | |
5c48580d MB |
2722 | int64_t should_be_frame = should_be_frame_32; |
2723 | should_be_frame = should_be_frame * conn->output_sample_ratio; | |
cca403c2 | 2724 | |
5c48580d MB |
2725 | // current_delay is denominated in the frame rate of the outgoing stream |
2726 | int64_t will_be_frame = inframe->given_timestamp; | |
2727 | will_be_frame = will_be_frame * conn->output_sample_ratio; | |
7b8e6865 MB |
2728 | will_be_frame = (will_be_frame - current_delay) & |
2729 | output_rtptime_mask; // this is to make sure it's unsigned modulo 2^bits | |
2730 | // for the rtptime | |
2731 | ||
2732 | // Now we have a tricky piece of calculation to perform. | |
2733 | // We know the rtptimes are unsigned in 32 or more bits -- call it r bits. We have to | |
2734 | // calculate the difference between them. on the basis that they should be within | |
2735 | // 2^(r-1) of one another, so that the unsigned subtraction result, modulo 2^r, if | |
2736 | // interpreted as a signed number, should yield the difference _and_ the ordering. | |
2737 | ||
2738 | sync_error = should_be_frame - will_be_frame; // this is done in int64_t form | |
fd880056 | 2739 | |
1ca2487b MB |
2740 | // int64_t t_ping = should_be_frame - conn->anchor_rtptime; |
2741 | // if (t_ping < 0) | |
fd880056 MB |
2742 | // debug(1, "Frame %" PRIu64 " is %" PRId64 " frames before anchor time %" PRIu64 ".", |
2743 | // should_be_frame, -t_ping, conn->anchor_rtptime); | |
7b8e6865 MB |
2744 | |
2745 | // sign-extend the r-bit unsigned int calculation by treating it as an r-bit signed | |
2746 | // integer | |
2747 | if ((sync_error & output_rtptime_sign_mask) != | |
2748 | 0) { // check what would be the sign bit in "r" bit unsigned arithmetic | |
2749 | // result is negative | |
2750 | sync_error = sync_error | output_rtptime_mask_not; | |
2751 | } else { | |
2752 | // result is positive | |
2753 | sync_error = sync_error & output_rtptime_mask; | |
2754 | } | |
2b88215f | 2755 | |
54d761ff | 2756 | if (at_least_one_frame_seen_this_session == 0) { |
ca562872 | 2757 | at_least_one_frame_seen_this_session = 1; |
02c0a159 | 2758 | #ifdef CONFIG_METADATA |
7c1a5fd0 | 2759 | this_is_the_first_frame = 1; |
02c0a159 | 2760 | #endif |
54d761ff | 2761 | |
ca562872 MB |
2762 | // debug(2,"first frame real sync error (positive --> late): %" PRId64 " frames.", |
2763 | // sync_error); | |
54d761ff | 2764 | |
ca562872 MB |
2765 | // this is a sneaky attempt to make a final adjustment to the timing of the first |
2766 | // packet | |
54d761ff | 2767 | |
ca562872 MB |
2768 | // the very first packet generally has a first_frame_early_bias subtracted from its |
2769 | // timing to make it more likely that it will be early than late, making it possible | |
2770 | // to compensate for it be adding a few frames of silence. | |
54d761ff | 2771 | |
ca562872 MB |
2772 | // debug(2,"first frame real sync error (positive --> late): %" PRId64 " frames.", |
2773 | // sync_error); | |
54d761ff | 2774 | |
ca562872 | 2775 | // remove the bias when reporting the error to make it the true error |
a109b587 | 2776 | debug(2, |
ca562872 MB |
2777 | "first frame sync error (positive --> late): %" PRId64 |
2778 | " frames, %.3f mS at %d frames per second output.", | |
2779 | sync_error + first_frame_early_bias, | |
2780 | (1000.0 * (sync_error + first_frame_early_bias)) / config.output_rate, | |
2781 | config.output_rate); | |
2782 | ||
2783 | // if the packet is early, add the frames needed to put it in sync. | |
2784 | if (sync_error < 0) { | |
2785 | size_t final_adjustment_length_sized = -sync_error; | |
2786 | char *final_adjustment_silence = | |
2787 | malloc(conn->output_bytes_per_frame * final_adjustment_length_sized); | |
54d761ff MB |
2788 | if (final_adjustment_silence) { |
2789 | ||
ca562872 MB |
2790 | conn->previous_random_number = generate_zero_frames( |
2791 | final_adjustment_silence, final_adjustment_length_sized, config.output_format, | |
2792 | conn->enable_dither, conn->previous_random_number); | |
54d761ff MB |
2793 | int final_adjustment = -sync_error; |
2794 | final_adjustment = final_adjustment - first_frame_early_bias; | |
ca562872 MB |
2795 | debug(2, |
2796 | "final sync adjustment: %" PRId64 | |
2797 | " silent frames added with a bias of %" PRId64 " frames.", | |
2798 | -sync_error, first_frame_early_bias); | |
fd880056 MB |
2799 | config.output->play(final_adjustment_silence, final_adjustment_length_sized, |
2800 | play_samples_are_untimed, 0, 0); | |
54d761ff MB |
2801 | free(final_adjustment_silence); |
2802 | } else { | |
ca562872 MB |
2803 | warn("Failed to allocate memory for a final_adjustment_silence buffer of %d " |
2804 | "frames for a " | |
54d761ff MB |
2805 | "sync error of %d frames.", |
2806 | final_adjustment_length_sized, sync_error); | |
2807 | } | |
2808 | sync_error = 0; // say the error was fixed! | |
2809 | } | |
1d228870 | 2810 | // since this is the first frame of audio, inform the user if requested... |
1d228870 | 2811 | #ifdef CONFIG_AIRPLAY_2 |
d67909b8 MB |
2812 | if (conn->airplay_stream_type == realtime_stream) { |
2813 | if (conn->airplay_type == ap_1) { | |
7c1a5fd0 | 2814 | #ifdef CONFIG_METADATA |
d67909b8 | 2815 | send_ssnc_metadata('styp', "Classic", strlen("Classic"), 1); |
61865bf3 | 2816 | #endif |
d67909b8 | 2817 | if (config.statistics_requested) |
e8b8c6ed | 2818 | inform("Connection %d: Playback started at frame %" PRId64 |
02c0a159 | 2819 | " -- Classic AirPlay (\"AirPlay 1\") Compatible.", |
e8b8c6ed | 2820 | conn->connection_number, inframe->given_timestamp); |
1d228870 | 2821 | } else { |
7c1a5fd0 | 2822 | #ifdef CONFIG_METADATA |
d67909b8 | 2823 | send_ssnc_metadata('styp', "Realtime", strlen("Realtime"), 1); |
61865bf3 | 2824 | #endif |
d67909b8 | 2825 | if (config.statistics_requested) |
e8b8c6ed MB |
2826 | inform("Connection %d: Playback started at frame %" PRId64 |
2827 | " -- AirPlay 2 Realtime.", | |
2828 | conn->connection_number, inframe->given_timestamp); | |
1d228870 | 2829 | } |
d67909b8 | 2830 | } else { |
7c1a5fd0 | 2831 | #ifdef CONFIG_METADATA |
d67909b8 | 2832 | send_ssnc_metadata('styp', "Buffered", strlen("Buffered"), 1); |
61865bf3 | 2833 | #endif |
d67909b8 | 2834 | if (config.statistics_requested) |
e8b8c6ed MB |
2835 | inform("Connection %d: Playback started at frame %" PRId64 |
2836 | " -- AirPlay 2 Buffered.", | |
2837 | conn->connection_number, inframe->given_timestamp); | |
d67909b8 | 2838 | } |
1d228870 | 2839 | #else |
7c1a5fd0 | 2840 | #ifdef CONFIG_METADATA |
d67909b8 | 2841 | send_ssnc_metadata('styp', "Classic", strlen("Classic"), 1); |
61865bf3 | 2842 | #endif |
d67909b8 | 2843 | if (config.statistics_requested) |
d6536a8e MB |
2844 | inform("Connection %d: Playback started at frame %" PRId64 |
2845 | " -- Classic AirPlay (\"AirPlay 1\").", | |
e8b8c6ed | 2846 | conn->connection_number, inframe->given_timestamp); |
1d228870 | 2847 | #endif |
54d761ff | 2848 | } |
d9c0028f MB |
2849 | // not too sure if abs() is implemented for int64_t, so we'll do it manually |
2850 | int64_t abs_sync_error = sync_error; | |
2851 | if (abs_sync_error < 0) | |
2852 | abs_sync_error = -abs_sync_error; | |
87a0475c | 2853 | |
de071aef | 2854 | if ((config.no_sync == 0) && (inframe->given_timestamp != 0) && |
28f54af2 MB |
2855 | (config.resync_threshold > 0.0) && |
2856 | (abs_sync_error > config.resync_threshold * config.output_rate)) { | |
d9c0028f MB |
2857 | sync_error_out_of_bounds++; |
2858 | } else { | |
2859 | sync_error_out_of_bounds = 0; | |
c887aafd | 2860 | } |
b4d676fe | 2861 | |
d9c0028f | 2862 | if (sync_error_out_of_bounds > 3) { |
e7098c45 | 2863 | // debug(1, "lost sync with source for %d consecutive packets -- flushing and " |
9ba3ed39 MB |
2864 | // "resyncing. Error: %lld.", |
2865 | // sync_error_out_of_bounds, sync_error); | |
d9c0028f | 2866 | sync_error_out_of_bounds = 0; |
c887aafd | 2867 | |
e7098c45 MB |
2868 | uint64_t frames_sent_for_play = 0; |
2869 | uint64_t actual_delay = 0; | |
b4d676fe | 2870 | |
e7098c45 MB |
2871 | if ((config.output->delay) && (config.no_sync == 0) && (config.output->stats)) { |
2872 | uint64_t raw_measurement_time; | |
2873 | uint64_t corrected_measurement_time; | |
2874 | config.output->stats(&raw_measurement_time, &corrected_measurement_time, | |
b4d676fe | 2875 | &actual_delay, &frames_sent_for_play); |
e7098c45 MB |
2876 | } |
2877 | ||
ccc4fe09 | 2878 | int64_t filler_length = |
28f54af2 | 2879 | (int64_t)(config.resync_threshold * config.output_rate); // number of samples |
d9c0028f | 2880 | if ((sync_error > 0) && (sync_error > filler_length)) { |
a109b587 | 2881 | debug(1, |
fd880056 | 2882 | "Large positive (i.e. late) sync error of %" PRId64 |
e7098c45 | 2883 | " frames (%f seconds), at frame: %" PRIu32 ".", |
a109b587 MB |
2884 | sync_error, (sync_error * 1.0) / config.output_rate, |
2885 | inframe->given_timestamp); | |
fd880056 MB |
2886 | // debug(1, "%" PRId64 " frames sent to DAC. DAC buffer contains %" PRId64 " |
2887 | // frames.", | |
1ca2487b | 2888 | // frames_sent_for_play, actual_delay); |
b4d676fe MB |
2889 | // the sync error is output frames, but we have to work out how many source frames |
2890 | // to drop there may be a multiple (the conn->output_sample_ratio) of output frames | |
2891 | // per input frame... | |
e7098c45 | 2892 | int64_t source_frames_to_drop = sync_error; |
b4d676fe MB |
2893 | source_frames_to_drop = source_frames_to_drop / conn->output_sample_ratio; |
2894 | ||
28f54af2 | 2895 | // drop some extra frames to give the pipeline a chance to recover |
d2ca8c84 MB |
2896 | int64_t extra_frames_to_drop = |
2897 | (int64_t)(conn->input_rate * config.resync_recovery_time); | |
e7098c45 MB |
2898 | source_frames_to_drop += extra_frames_to_drop; |
2899 | ||
2900 | uint32_t frames_to_drop = source_frames_to_drop; | |
2901 | uint32_t flush_to_frame = inframe->given_timestamp + frames_to_drop; | |
b4d676fe | 2902 | |
e7098c45 | 2903 | do_flush(flush_to_frame, conn); |
bcad9d59 | 2904 | |
d9c0028f | 2905 | } else if ((sync_error < 0) && ((-sync_error) > filler_length)) { |
fd4cc98a | 2906 | debug(1, |
fd880056 | 2907 | "Large negative (i.e. early) sync error of %" PRId64 |
e7098c45 | 2908 | " frames (%f seconds), at frame: %" PRIu32 ".", |
a109b587 MB |
2909 | sync_error, (sync_error * 1.0) / config.output_rate, |
2910 | inframe->given_timestamp); | |
fd880056 | 2911 | debug(3, "%" PRId64 " frames sent to DAC. DAC buffer contains %" PRId64 " frames.", |
e7098c45 | 2912 | frames_sent_for_play, actual_delay); |
8914b68b | 2913 | int64_t silence_length = -sync_error; |
3001f39b MB |
2914 | if (silence_length > (filler_length * 5)) |
2915 | silence_length = filler_length * 5; | |
8914b68b MB |
2916 | size_t silence_length_sized = silence_length; |
2917 | char *long_silence = malloc(conn->output_bytes_per_frame * silence_length_sized); | |
6c7b26a6 | 2918 | if (long_silence) { |
4046c0e7 MB |
2919 | |
2920 | conn->previous_random_number = | |
2921 | generate_zero_frames(long_silence, silence_length_sized, config.output_format, | |
2922 | conn->enable_dither, conn->previous_random_number); | |
2923 | ||
ccc4fe09 | 2924 | debug(2, "Play a silence of %d frames.", silence_length_sized); |
fd880056 MB |
2925 | config.output->play(long_silence, silence_length_sized, play_samples_are_untimed, |
2926 | 0, 0); | |
6c7b26a6 MB |
2927 | free(long_silence); |
2928 | } else { | |
76c5dd92 | 2929 | warn("Failed to allocate memory for a long_silence buffer of %d frames for a " |
8914b68b MB |
2930 | "sync error of %d frames.", |
2931 | silence_length_sized, sync_error); | |
6c7b26a6 | 2932 | } |
3cb359c7 | 2933 | reset_input_flow_metrics(conn); |
d9c0028f MB |
2934 | } |
2935 | } else { | |
064bd293 | 2936 | |
2a4abea6 | 2937 | /* |
d9c0028f | 2938 | // before we finally commit to this frame, check its sequencing and timing |
d9c0028f MB |
2939 | // require a certain error before bothering to fix it... |
2940 | if (sync_error > config.tolerance * config.output_rate) { // int64_t > int, okay | |
2941 | amount_to_stuff = -1; | |
2942 | } | |
2943 | if (sync_error < -config.tolerance * config.output_rate) { | |
2944 | amount_to_stuff = 1; | |
2945 | } | |
2a4abea6 | 2946 | */ |
754155ce MB |
2947 | |
2948 | if (amount_to_stuff == 0) { | |
2a4abea6 MB |
2949 | // use a "V" shaped function to decide if stuffing should occur |
2950 | int64_t s = r64i(); | |
754155ce | 2951 | s = s >> 31; |
2a4abea6 | 2952 | s = s * config.tolerance * config.output_rate; |
754155ce MB |
2953 | s = (s >> 32) + config.tolerance * config.output_rate; // should be a number from 0 |
2954 | // to config.tolerance * | |
2955 | // config.output_rate; | |
2956 | if ((sync_error > 0) && (sync_error > s)) { | |
2957 | // debug(1,"Extra stuff -1"); | |
2a4abea6 MB |
2958 | amount_to_stuff = -1; |
2959 | } | |
754155ce MB |
2960 | if ((sync_error < 0) && (sync_error < (-s))) { |
2961 | // debug(1,"Extra stuff +1"); | |
2a4abea6 | 2962 | amount_to_stuff = 1; |
754155ce | 2963 | } |
d9c0028f | 2964 | } |
754155ce | 2965 | |
d9c0028f | 2966 | // try to keep the corrections definitely below 1 in 1000 audio frames |
064bd293 | 2967 | |
d9c0028f | 2968 | // calculate the time elapsed since the play session started. |
97030073 | 2969 | |
d9c0028f MB |
2970 | if (amount_to_stuff) { |
2971 | if ((local_time_now) && (conn->first_packet_time_to_play) && | |
2972 | (local_time_now >= conn->first_packet_time_to_play)) { | |
2973 | ||
54d761ff MB |
2974 | int64_t tp = |
2975 | (local_time_now - conn->first_packet_time_to_play) / | |
2976 | 1000000000; // seconds int64_t from uint64_t which is always positive, so ok | |
d9c0028f MB |
2977 | |
2978 | if (tp < 5) | |
2979 | amount_to_stuff = 0; // wait at least five seconds | |
2980 | /* | |
2981 | else if (tp < 30) { | |
2982 | if ((random() % 1000) > | |
2983 | 352) // keep it to about 1:1000 for the first thirty seconds | |
2984 | amount_to_stuff = 0; | |
2985 | } | |
2986 | */ | |
97030073 MB |
2987 | } |
2988 | } | |
064bd293 | 2989 | |
d9c0028f MB |
2990 | if (config.no_sync != 0) |
2991 | amount_to_stuff = 0; // no stuffing if it's been disabled | |
945483d9 | 2992 | |
d9c0028f | 2993 | // Apply DSP here |
67e9b1b6 | 2994 | |
54d761ff MB |
2995 | // check the state of loudness and convolution flags here and don't change them for |
2996 | // the frame | |
67e9b1b6 | 2997 | |
f2930387 | 2998 | int do_loudness = config.loudness; |
67e9b1b6 | 2999 | |
b88c9255 | 3000 | #ifdef CONFIG_CONVOLUTION |
f2930387 MB |
3001 | int do_convolution = 0; |
3002 | if ((config.convolution) && (config.convolver_valid)) | |
3003 | do_convolution = 1; | |
b88c9255 | 3004 | |
54d761ff MB |
3005 | // we will apply the convolution gain if convolution is enabled, even if there is no |
3006 | // valid convolution happening | |
67e9b1b6 | 3007 | |
f2930387 MB |
3008 | int convolution_is_enabled = 0; |
3009 | if (config.convolution) | |
3010 | convolution_is_enabled = 1; | |
b88c9255 | 3011 | #endif |
67e9b1b6 | 3012 | |
f2930387 | 3013 | if (do_loudness |
7b9cd28e | 3014 | #ifdef CONFIG_CONVOLUTION |
f2930387 | 3015 | || convolution_is_enabled |
7b9cd28e | 3016 | #endif |
54d761ff | 3017 | ) { |
d3b79b96 | 3018 | int32_t *tbuf32 = (int32_t *)conn->tbuf; |
d9c0028f MB |
3019 | float fbuf_l[inbuflength]; |
3020 | float fbuf_r[inbuflength]; | |
3021 | ||
3022 | // Deinterleave, and convert to float | |
3023 | int i; | |
3024 | for (i = 0; i < inbuflength; ++i) { | |
3025 | fbuf_l[i] = tbuf32[2 * i]; | |
3026 | fbuf_r[i] = tbuf32[2 * i + 1]; | |
3027 | } | |
3028 | ||
7b9cd28e | 3029 | #ifdef CONFIG_CONVOLUTION |
d9c0028f | 3030 | // Apply convolution |
f2930387 | 3031 | if (do_convolution) { |
d9c0028f MB |
3032 | convolver_process_l(fbuf_l, inbuflength); |
3033 | convolver_process_r(fbuf_r, inbuflength); | |
f2930387 MB |
3034 | } |
3035 | if (convolution_is_enabled) { | |
d9c0028f MB |
3036 | float gain = pow(10.0, config.convolution_gain / 20.0); |
3037 | for (i = 0; i < inbuflength; ++i) { | |
3038 | fbuf_l[i] *= gain; | |
3039 | fbuf_r[i] *= gain; | |
3040 | } | |
7b9cd28e | 3041 | } |
7b9cd28e | 3042 | #endif |
d9c0028f | 3043 | |
f2930387 | 3044 | if (do_loudness) { |
d9c0028f MB |
3045 | // Apply volume and loudness |
3046 | // Volume must be applied here because the loudness filter will increase the | |
3047 | // signal level and it would saturate the int32_t otherwise | |
ea46a09a | 3048 | float gain = conn->fix_volume / 65536.0f; |
07e46565 | 3049 | // float gain_db = 20 * log10(gain); |
d9c0028f MB |
3050 | // debug(1, "Applying soft volume dB: %f k: %f", gain_db, gain); |
3051 | ||
3052 | for (i = 0; i < inbuflength; ++i) { | |
3053 | fbuf_l[i] = loudness_process(&loudness_l, fbuf_l[i] * gain); | |
3054 | fbuf_r[i] = loudness_process(&loudness_r, fbuf_r[i] * gain); | |
3055 | } | |
3056 | } | |
3057 | ||
3058 | // Interleave and convert back to int32_t | |
3059 | for (i = 0; i < inbuflength; ++i) { | |
3060 | tbuf32[2 * i] = fbuf_l[i]; | |
3061 | tbuf32[2 * i + 1] = fbuf_r[i]; | |
7b9cd28e YP |
3062 | } |
3063 | } | |
754155ce | 3064 | |
9aa8f91c | 3065 | #ifdef CONFIG_SOXR |
2ca6e42b | 3066 | if ((current_delay < conn->dac_buffer_queue_minimum_length) || |
9aa8f91c | 3067 | (config.packet_stuffing == ST_basic) || |
14bfba27 | 3068 | (config.soxr_delay_index == 0) || // not computed |
c8b0be30 MB |
3069 | ((config.packet_stuffing == ST_auto) && |
3070 | (config.soxr_delay_index > | |
3071 | config.soxr_delay_threshold)) // if the CPU is deemed too slow | |
54d761ff | 3072 | ) { |
9aa8f91c | 3073 | #endif |
064bd293 | 3074 | play_samples = |
d3b79b96 | 3075 | stuff_buffer_basic_32((int32_t *)conn->tbuf, inbuflength, config.output_format, |
4046c0e7 | 3076 | conn->outbuf, amount_to_stuff, conn->enable_dither, conn); |
c9b3d2a2 | 3077 | #ifdef CONFIG_SOXR |
c8b0be30 MB |
3078 | } else { // soxr requested or auto requested with the index less or equal to the |
3079 | // threshold | |
c8c70b60 MB |
3080 | play_samples = stuff_buffer_soxr_32((int32_t *)conn->tbuf, (int32_t *)conn->sbuf, |
3081 | inbuflength, config.output_format, conn->outbuf, | |
4046c0e7 | 3082 | amount_to_stuff, conn->enable_dither, conn); |
2239efe8 | 3083 | } |
2a4abea6 | 3084 | #endif |
064bd293 | 3085 | |
d9c0028f MB |
3086 | /* |
3087 | { | |
3088 | int co; | |
3089 | int is_silent=1; | |
3090 | short *p = outbuf; | |
3091 | for (co=0;co<play_samples;co++) { | |
3092 | if (*p!=0) | |
3093 | is_silent=0; | |
3094 | p++; | |
3095 | } | |
3096 | if (is_silent) | |
3097 | debug(1,"Silence!"); | |
3098 | } | |
3099 | */ | |
3100 | ||
d3b79b96 | 3101 | if (conn->outbuf == NULL) |
d9c0028f MB |
3102 | debug(1, "NULL outbuf to play -- skipping it."); |
3103 | else { | |
3104 | if (play_samples == 0) | |
3105 | debug(1, "play_samples==0 skipping it (1)."); | |
c5ff0dfe MB |
3106 | else { |
3107 | if (conn->software_mute_enabled) { | |
555bb97a MB |
3108 | generate_zero_frames(conn->outbuf, play_samples, config.output_format, |
3109 | conn->enable_dither, conn->previous_random_number); | |
c5ff0dfe | 3110 | } |
fd880056 MB |
3111 | uint64_t should_be_time; |
3112 | frame_to_local_time(inframe->given_timestamp, &should_be_time, conn); | |
40446668 | 3113 | |
50738c36 MB |
3114 | config.output->play(conn->outbuf, play_samples, play_samples_are_timed, |
3115 | inframe->given_timestamp, should_be_time); | |
7c1a5fd0 | 3116 | #ifdef CONFIG_METADATA |
40446668 MB |
3117 | // debug(1,"config.metadata_progress_interval is %f.", |
3118 | // config.metadata_progress_interval); | |
7c1a5fd0 MB |
3119 | if (config.metadata_progress_interval != 0.0) { |
3120 | char hb[128]; | |
3121 | if (this_is_the_first_frame != 0) { | |
3122 | memset(hb, 0, 128); | |
40446668 MB |
3123 | snprintf(hb, 127, "%" PRIu32 "/%" PRId64 "", inframe->given_timestamp, |
3124 | should_be_time); | |
37f060f4 | 3125 | send_ssnc_metadata('phb0', hb, strlen(hb), 1); |
7c1a5fd0 MB |
3126 | send_ssnc_metadata('phbt', hb, strlen(hb), 1); |
3127 | time_of_last_metadata_progress_update = local_time_now; | |
3128 | } else { | |
3129 | uint64_t mx = 1000000000; | |
3130 | uint64_t iv = config.metadata_progress_interval * mx; | |
3131 | iv = iv + time_of_last_metadata_progress_update; | |
3132 | int64_t delta = iv - local_time_now; | |
3133 | if (delta <= 0) { | |
3134 | memset(hb, 0, 128); | |
40446668 MB |
3135 | snprintf(hb, 127, "%" PRIu32 "/%" PRId64 "", inframe->given_timestamp, |
3136 | should_be_time); | |
7c1a5fd0 MB |
3137 | send_ssnc_metadata('phbt', hb, strlen(hb), 1); |
3138 | time_of_last_metadata_progress_update = local_time_now; | |
3139 | } | |
40446668 | 3140 | } |
7c1a5fd0 MB |
3141 | } |
3142 | #endif | |
c5ff0dfe | 3143 | } |
d9c0028f | 3144 | } |
064bd293 | 3145 | |
d9c0028f MB |
3146 | // check for loss of sync |
3147 | // timestamp of zero means an inserted silent frame in place of a missing frame | |
3148 | /* | |
3149 | if ((config.no_sync == 0) && (inframe->timestamp != 0) && | |
28f54af2 MB |
3150 | && (config.resync_threshold > 0.0) && |
3151 | (abs_sync_error > config.resync_threshold * config.output_rate)) { | |
d9c0028f MB |
3152 | sync_error_out_of_bounds++; |
3153 | // debug(1,"Sync error out of bounds: Error: %lld; previous error: %lld; DAC: %lld; | |
3154 | // timestamp: %llx, time now | |
9ba3ed39 MB |
3155 | // |
3156 | %llx",sync_error,previous_sync_error,current_delay,inframe->timestamp,local_time_now); | |
d9c0028f MB |
3157 | if (sync_error_out_of_bounds > 3) { |
3158 | debug(1, "Lost sync with source for %d consecutive packets -- flushing and " | |
3159 | "resyncing. Error: %lld.", | |
3160 | sync_error_out_of_bounds, sync_error); | |
3161 | sync_error_out_of_bounds = 0; | |
3162 | player_flush(nt, conn); | |
3163 | } | |
3164 | } else { | |
c887aafd | 3165 | sync_error_out_of_bounds = 0; |
87a0475c | 3166 | } |
d9c0028f | 3167 | */ |
c887aafd | 3168 | } |
771aa1a1 | 3169 | } else { |
dfd90bac | 3170 | |
dfd90bac MB |
3171 | // if this is the first frame, see if it's close to when it's supposed to be |
3172 | // release, which will be its time plus latency and any offset_time | |
3173 | if (at_least_one_frame_seen_this_session == 0) { | |
02c0a159 | 3174 | #ifdef CONFIG_METADATA |
7c1a5fd0 | 3175 | this_is_the_first_frame = 1; |
02c0a159 | 3176 | #endif |
ca562872 | 3177 | at_least_one_frame_seen_this_session = 1; |
dfd90bac MB |
3178 | } |
3179 | ||
c8c70b60 MB |
3180 | play_samples = |
3181 | stuff_buffer_basic_32((int32_t *)conn->tbuf, inbuflength, config.output_format, | |
4046c0e7 | 3182 | conn->outbuf, 0, conn->enable_dither, conn); |
d3b79b96 | 3183 | if (conn->outbuf == NULL) |
c9910540 | 3184 | debug(1, "NULL outbuf to play -- skipping it."); |
c5ff0dfe MB |
3185 | else { |
3186 | if (conn->software_mute_enabled) { | |
555bb97a MB |
3187 | generate_zero_frames(conn->outbuf, play_samples, config.output_format, |
3188 | conn->enable_dither, conn->previous_random_number); | |
c5ff0dfe | 3189 | } |
fd880056 MB |
3190 | uint64_t should_be_time; |
3191 | frame_to_local_time(inframe->given_timestamp, &should_be_time, conn); | |
50738c36 MB |
3192 | config.output->play(conn->outbuf, play_samples, play_samples_are_timed, |
3193 | inframe->given_timestamp, should_be_time); | |
7c1a5fd0 | 3194 | #ifdef CONFIG_METADATA |
40446668 MB |
3195 | // debug(1,"config.metadata_progress_interval is %f.", |
3196 | // config.metadata_progress_interval); | |
7c1a5fd0 MB |
3197 | if (config.metadata_progress_interval != 0.0) { |
3198 | char hb[128]; | |
3199 | if (this_is_the_first_frame != 0) { | |
3200 | memset(hb, 0, 128); | |
40446668 MB |
3201 | snprintf(hb, 127, "%" PRIu32 "/%" PRId64 "", inframe->given_timestamp, |
3202 | should_be_time); | |
37f060f4 | 3203 | send_ssnc_metadata('phb0', hb, strlen(hb), 1); |
7c1a5fd0 MB |
3204 | send_ssnc_metadata('phbt', hb, strlen(hb), 1); |
3205 | time_of_last_metadata_progress_update = local_time_now; | |
3206 | } else { | |
3207 | uint64_t mx = 1000000000; | |
3208 | uint64_t iv = config.metadata_progress_interval * mx; | |
3209 | iv = iv + time_of_last_metadata_progress_update; | |
3210 | int64_t delta = iv - local_time_now; | |
3211 | if (delta <= 0) { | |
3212 | memset(hb, 0, 128); | |
40446668 MB |
3213 | snprintf(hb, 127, "%" PRIu32 "/%" PRId64 "", inframe->given_timestamp, |
3214 | should_be_time); | |
7c1a5fd0 MB |
3215 | send_ssnc_metadata('phbt', hb, strlen(hb), 1); |
3216 | time_of_last_metadata_progress_update = local_time_now; | |
3217 | } | |
40446668 | 3218 | } |
7c1a5fd0 MB |
3219 | } |
3220 | #endif | |
c5ff0dfe | 3221 | } |
771aa1a1 | 3222 | } |
391b48f6 | 3223 | |
87a0475c | 3224 | // mark the frame as finished |
de071aef | 3225 | inframe->given_timestamp = 0; |
391b48f6 | 3226 | inframe->sequence_number = 0; |
e2294dec MB |
3227 | inframe->resend_time = 0; |
3228 | inframe->initialisation_time = 0; | |
87a0475c | 3229 | |
0ca5fd3c MB |
3230 | // if we've just printed out statistics, note that in the next interval |
3231 | // we haven't seen any frames yet | |
3232 | ||
3233 | if (play_number % print_interval == 0) { | |
3234 | frames_seen_in_this_logging_interval = 0; | |
3235 | } | |
3236 | ||
76ee6d5e MB |
3237 | // update the watchdog |
3238 | if ((config.dont_check_timeout == 0) && (config.timeout != 0)) { | |
67e9b1b6 | 3239 | uint64_t time_now = get_absolute_time_in_ns(); |
eaa98ea7 | 3240 | debug_mutex_lock(&conn->watchdog_mutex, 1000, 0); |
76ee6d5e | 3241 | conn->watchdog_bark_time = time_now; |
eaa98ea7 | 3242 | debug_mutex_unlock(&conn->watchdog_mutex, 0); |
76ee6d5e MB |
3243 | } |
3244 | ||
83b7049e | 3245 | // debug(1,"Sync error %lld frames. Amount to stuff %d." ,sync_error,amount_to_stuff); |
87a0475c MB |
3246 | |
3247 | // new stats calculation. We want a running average of sync error, drift, adjustment, | |
3248 | // number of additions+subtractions | |
064bd293 MB |
3249 | |
3250 | // this is a misleading hack -- the statistics should include some data on the number of | |
3251 | // valid samples and the number of times sync wasn't checked due to non availability of a | |
3252 | // delay figure. | |
cca403c2 | 3253 | // for the present, stats are only updated when sync has been checked |
759b87f2 | 3254 | if (config.output->delay != NULL) { |
cca403c2 MB |
3255 | if (number_of_statistics == trend_interval) { |
3256 | // here we remove the oldest statistical data and take it from the summaries as well | |
759b87f2 MB |
3257 | tsum_of_sync_errors -= conn->statistics[oldest_statistic].sync_error; |
3258 | tsum_of_drifts -= conn->statistics[oldest_statistic].drift; | |
3259 | if (conn->statistics[oldest_statistic].correction > 0) | |
3260 | tsum_of_insertions_and_deletions -= conn->statistics[oldest_statistic].correction; | |
cca403c2 | 3261 | else |
759b87f2 MB |
3262 | tsum_of_insertions_and_deletions += conn->statistics[oldest_statistic].correction; |
3263 | tsum_of_corrections -= conn->statistics[oldest_statistic].correction; | |
cca403c2 MB |
3264 | oldest_statistic = (oldest_statistic + 1) % trend_interval; |
3265 | number_of_statistics--; | |
3266 | } | |
87a0475c | 3267 | |
759b87f2 MB |
3268 | conn->statistics[newest_statistic].sync_error = sync_error; |
3269 | conn->statistics[newest_statistic].correction = conn->amountStuffed; | |
771aa1a1 | 3270 | |
cca403c2 | 3271 | if (number_of_statistics == 0) |
759b87f2 | 3272 | conn->statistics[newest_statistic].drift = 0; |
cca403c2 | 3273 | else |
759b87f2 | 3274 | conn->statistics[newest_statistic].drift = |
cca403c2 | 3275 | sync_error - previous_sync_error - previous_correction; |
771aa1a1 | 3276 | |
cca403c2 | 3277 | previous_sync_error = sync_error; |
c9910540 | 3278 | previous_correction = conn->amountStuffed; |
771aa1a1 | 3279 | |
cca403c2 | 3280 | tsum_of_sync_errors += sync_error; |
759b87f2 | 3281 | tsum_of_drifts += conn->statistics[newest_statistic].drift; |
c9910540 MB |
3282 | if (conn->amountStuffed > 0) { |
3283 | tsum_of_insertions_and_deletions += conn->amountStuffed; | |
cca403c2 | 3284 | } else { |
c9910540 | 3285 | tsum_of_insertions_and_deletions -= conn->amountStuffed; |
cca403c2 | 3286 | } |
c9910540 MB |
3287 | tsum_of_corrections += conn->amountStuffed; |
3288 | conn->session_corrections += conn->amountStuffed; | |
300b4abe | 3289 | |
cca403c2 MB |
3290 | newest_statistic = (newest_statistic + 1) % trend_interval; |
3291 | number_of_statistics++; | |
064bd293 | 3292 | } |
7187b63e MB |
3293 | } |
3294 | } | |
a2fb5d21 | 3295 | } |
7187b63e | 3296 | } |
418b1ba7 | 3297 | |
c8c70b60 | 3298 | debug(1, "This should never be called."); |
58a66ebb | 3299 | pthread_cleanup_pop(1); // pop the cleanup handler |
998e7cea MB |
3300 | // debug(1, "This should never be called either."); |
3301 | // pthread_cleanup_pop(1); // pop the initial cleanup handler | |
ccc4fe09 | 3302 | pthread_exit(NULL); |
a2fb5d21 JL |
3303 | } |
3304 | ||
1e07e1e0 | 3305 | void player_volume_without_notification(double airplay_volume, rtsp_conn_info *conn) { |
601ac4d7 | 3306 | debug_mutex_lock(&conn->volume_control_mutex, 5000, 1); |
555bb97a MB |
3307 | // first, see if we are hw only, sw only, both with hw attenuation on the top or both with sw |
3308 | // attenuation on top | |
3309 | ||
3310 | enum volume_mode_type { vol_sw_only, vol_hw_only, vol_both } volume_mode; | |
c5ff0dfe | 3311 | |
555bb97a MB |
3312 | // take account of whether there is a hardware mixer, if a max volume has been specified and if a |
3313 | // range has been specified | |
c5ff0dfe | 3314 | // the range might imply that both hw and software mixers are needed, so calculate this |
555bb97a | 3315 | |
1fc1247b | 3316 | int32_t hw_max_db = 0, hw_min_db = 0; // zeroed to quieten an incorrect uninitialised warning |
c5ff0dfe | 3317 | int32_t sw_max_db = 0, sw_min_db = -9630; |
67e9b1b6 | 3318 | |
c5ff0dfe MB |
3319 | if (config.output->parameters) { |
3320 | volume_mode = vol_hw_only; | |
d9c0028f | 3321 | audio_parameters audio_information; |
a2790fc1 | 3322 | config.output->parameters(&audio_information); |
b74705b7 MB |
3323 | hw_max_db = audio_information.maximum_volume_dB; |
3324 | hw_min_db = audio_information.minimum_volume_dB; | |
c5ff0dfe MB |
3325 | if (config.volume_max_db_set) { |
3326 | if (((config.volume_max_db * 100) <= hw_max_db) && | |
3327 | ((config.volume_max_db * 100) >= hw_min_db)) | |
3328 | hw_max_db = (int32_t)config.volume_max_db * 100; | |
3329 | else if (config.volume_range_db) { | |
3330 | hw_max_db = hw_min_db; | |
3331 | sw_max_db = (config.volume_max_db * 100) - hw_min_db; | |
2a4a4ed2 | 3332 | } else { |
c5ff0dfe | 3333 | warn("The maximum output level is outside the range of the hardware mixer -- ignored"); |
555bb97a | 3334 | } |
cf29625d | 3335 | } |
555bb97a | 3336 | |
c5ff0dfe MB |
3337 | // here, we have set limits on the hw_max_db and the sw_max_db |
3338 | // but we haven't actually decided whether we need both hw and software attenuation | |
3339 | // only if a range is specified could we need both | |
3340 | if (config.volume_range_db) { | |
3341 | // see if the range requested exceeds the hardware range available | |
3342 | int32_t desired_range_db = (int32_t)trunc(config.volume_range_db * 100); | |
3343 | if ((desired_range_db) > (hw_max_db - hw_min_db)) { | |
3344 | volume_mode = vol_both; | |
3345 | int32_t desired_sw_range = desired_range_db - (hw_max_db - hw_min_db); | |
3346 | if ((sw_max_db - desired_sw_range) < sw_min_db) | |
3347 | warn("The range requested is too large to accommodate -- ignored."); | |
555bb97a | 3348 | else |
c5ff0dfe | 3349 | sw_min_db = (sw_max_db - desired_sw_range); |
d3c067d0 | 3350 | } else { |
04240708 | 3351 | hw_min_db = hw_max_db - desired_range_db; |
555bb97a | 3352 | } |
b74705b7 MB |
3353 | } |
3354 | } else { | |
c5ff0dfe MB |
3355 | // debug(1,"has no hardware mixer"); |
3356 | volume_mode = vol_sw_only; | |
3357 | if (config.volume_max_db_set) { | |
3358 | if (((config.volume_max_db * 100) <= sw_max_db) && | |
3359 | ((config.volume_max_db * 100) >= sw_min_db)) | |
555bb97a | 3360 | sw_max_db = (int32_t)config.volume_max_db * 100; |
b74705b7 | 3361 | } |
c5ff0dfe | 3362 | if (config.volume_range_db) { |
555bb97a MB |
3363 | // see if the range requested exceeds the software range available |
3364 | int32_t desired_range_db = (int32_t)trunc(config.volume_range_db * 100); | |
3365 | if ((desired_range_db) > (sw_max_db - sw_min_db)) | |
3366 | warn("The range requested is too large to accommodate -- ignored."); | |
3367 | else | |
3368 | sw_min_db = (sw_max_db - desired_range_db); | |
3369 | } | |
b74705b7 | 3370 | } |
555bb97a MB |
3371 | |
3372 | // here, we know whether it's hw volume control only, sw only or both, and we have the hw and sw | |
3373 | // limits. | |
c5ff0dfe MB |
3374 | // if it's both, we haven't decided whether hw or sw should be on top |
3375 | // we have to consider the settings ignore_volume_control and mute. | |
555bb97a | 3376 | |
3a6297bc MB |
3377 | if (airplay_volume == -144.0) { |
3378 | ||
3379 | if ((config.output->mute) && (config.output->mute(1) == 0)) | |
3380 | debug(2, | |
3381 | "player_volume_without_notification: volume mode is %d, airplay_volume is %f, " | |
3382 | "hardware mute is enabled.", | |
3383 | volume_mode, airplay_volume); | |
3384 | else { | |
3385 | conn->software_mute_enabled = 1; | |
3386 | debug(2, | |
3387 | "player_volume_without_notification: volume mode is %d, airplay_volume is %f, " | |
3388 | "software mute is enabled.", | |
3389 | volume_mode, airplay_volume); | |
3390 | } | |
3391 | ||
3392 | } else { | |
3393 | int32_t max_db = 0, min_db = 0; | |
3394 | switch (volume_mode) { | |
3395 | case vol_hw_only: | |
3396 | max_db = hw_max_db; | |
3397 | min_db = hw_min_db; | |
3398 | break; | |
3399 | case vol_sw_only: | |
3400 | max_db = sw_max_db; | |
3401 | min_db = sw_min_db; | |
3402 | break; | |
3403 | case vol_both: | |
3404 | // debug(1, "dB range passed is hw: %d, sw: %d, total: %d", hw_max_db - hw_min_db, | |
3405 | // sw_max_db - sw_min_db, (hw_max_db - hw_min_db) + (sw_max_db - sw_min_db)); | |
3406 | max_db = | |
3407 | (hw_max_db - hw_min_db) + (sw_max_db - sw_min_db); // this should be the range requested | |
3408 | min_db = 0; | |
3409 | break; | |
3410 | default: | |
3411 | debug(1, "player_volume_without_notification: error: not in a volume mode"); | |
3412 | break; | |
3413 | } | |
3414 | double scaled_attenuation = max_db; | |
3415 | if (config.ignore_volume_control == 0) { | |
c5ff0dfe | 3416 | |
c5ff0dfe MB |
3417 | if (config.volume_control_profile == VCP_standard) |
3418 | scaled_attenuation = vol2attn(airplay_volume, max_db, min_db); // no cancellation points | |
3419 | else if (config.volume_control_profile == VCP_flat) | |
555bb97a MB |
3420 | scaled_attenuation = |
3421 | flat_vol2attn(airplay_volume, max_db, min_db); // no cancellation points | |
ebe1ca17 | 3422 | else if (config.volume_control_profile == VCP_dasl_tapered) |
baf51cf2 | 3423 | scaled_attenuation = |
ebe1ca17 | 3424 | dasl_tapered_vol2attn(airplay_volume, max_db, min_db); // no cancellation points |
c5ff0dfe | 3425 | else |
60487c86 | 3426 | debug(1, "player_volume_without_notification: unrecognised volume control profile"); |
3a6297bc MB |
3427 | } |
3428 | // so here we have the scaled attenuation. If it's for hw or sw only, it's straightforward. | |
3429 | double hardware_attenuation = 0.0; | |
3430 | double software_attenuation = 0.0; | |
555bb97a | 3431 | |
3a6297bc MB |
3432 | switch (volume_mode) { |
3433 | case vol_hw_only: | |
3434 | hardware_attenuation = scaled_attenuation; | |
3435 | break; | |
3436 | case vol_sw_only: | |
3437 | software_attenuation = scaled_attenuation; | |
3438 | break; | |
3439 | case vol_both: | |
3440 | // here, we now the attenuation required, so we have to apportion it to the sw and hw mixers | |
3441 | // if we give the hw priority, that means when lowering the volume, set the hw volume to its | |
3442 | // lowest | |
3443 | // before using the sw attenuation. | |
3444 | // similarly, if we give the sw priority, that means when lowering the volume, set the sw | |
3445 | // volume to its lowest | |
3446 | // before using the hw attenuation. | |
3447 | // one imagines that hw priority is likely to be much better | |
3448 | // if (config.volume_range_hw_priority) { | |
3449 | if (config.volume_range_hw_priority != 0) { | |
3450 | // hw priority | |
3451 | if ((sw_max_db - sw_min_db) > scaled_attenuation) { | |
3452 | software_attenuation = sw_min_db + scaled_attenuation; | |
3453 | hardware_attenuation = hw_min_db; | |
555bb97a | 3454 | } else { |
3a6297bc MB |
3455 | software_attenuation = sw_max_db; |
3456 | hardware_attenuation = hw_min_db + scaled_attenuation - (sw_max_db - sw_min_db); | |
3457 | } | |
3458 | } else { | |
3459 | // sw priority | |
3460 | if ((hw_max_db - hw_min_db) > scaled_attenuation) { | |
3461 | hardware_attenuation = hw_min_db + scaled_attenuation; | |
3462 | software_attenuation = sw_min_db; | |
3463 | } else { | |
3464 | hardware_attenuation = hw_max_db; | |
3465 | software_attenuation = sw_min_db + scaled_attenuation - (hw_max_db - hw_min_db); | |
555bb97a | 3466 | } |
fd08511f | 3467 | } |
3a6297bc MB |
3468 | break; |
3469 | default: | |
3470 | debug(1, "player_volume_without_notification: error: not in a volume mode"); | |
3471 | break; | |
3472 | } | |
555bb97a | 3473 | |
3a6297bc MB |
3474 | if (((volume_mode == vol_hw_only) || (volume_mode == vol_both)) && (config.output->volume)) { |
3475 | config.output->volume(hardware_attenuation); // otherwise set the output to the lowest value | |
3476 | // debug(1,"Hardware attenuation set to %f for airplay volume of | |
3477 | // %f.",hardware_attenuation,airplay_volume); | |
3478 | if (volume_mode == vol_hw_only) | |
3479 | conn->fix_volume = 0x10000; | |
3480 | } | |
c5ff0dfe | 3481 | |
3a6297bc MB |
3482 | if ((volume_mode == vol_sw_only) || (volume_mode == vol_both)) { |
3483 | double temp_fix_volume = 65536.0 * pow(10, software_attenuation / 2000); | |
c5ff0dfe | 3484 | |
3a6297bc MB |
3485 | if (config.ignore_volume_control == 0) |
3486 | debug(2, "Software attenuation set to %f, i.e %f out of 65,536, for airplay volume of %f", | |
3487 | software_attenuation, temp_fix_volume, airplay_volume); | |
3488 | else | |
3489 | debug(2, "Software attenuation set to %f, i.e %f out of 65,536. Volume control is ignored.", | |
3490 | software_attenuation, temp_fix_volume); | |
67e9b1b6 | 3491 | |
3a6297bc | 3492 | conn->fix_volume = temp_fix_volume; |
b59dd422 | 3493 | |
3a6297bc MB |
3494 | // if (config.loudness) |
3495 | loudness_set_volume(software_attenuation / 100); | |
3496 | } | |
555bb97a | 3497 | |
3a6297bc MB |
3498 | if (config.logOutputLevel) { |
3499 | inform("Output Level set to: %.2f dB.", scaled_attenuation / 100.0); | |
c5ff0dfe | 3500 | } |
b59dd422 MB |
3501 | |
3502 | #ifdef CONFIG_METADATA | |
54d761ff MB |
3503 | // here, send the 'pvol' metadata message when the airplay volume information |
3504 | // is being used by shairport sync to control the output volume | |
ca562872 MB |
3505 | char dv[128]; |
3506 | memset(dv, 0, 128); | |
f135d857 MB |
3507 | if (config.ignore_volume_control == 0) { |
3508 | if (volume_mode == vol_both) { | |
3509 | // normalise the maximum output to the hardware device's max output | |
3510 | snprintf(dv, 127, "%.2f,%.2f,%.2f,%.2f", airplay_volume, | |
3511 | (scaled_attenuation - max_db + hw_max_db) / 100.0, | |
3512 | (min_db - max_db + hw_max_db) / 100.0, (max_db - max_db + hw_max_db) / 100.0); | |
3513 | } else { | |
3514 | snprintf(dv, 127, "%.2f,%.2f,%.2f,%.2f", airplay_volume, scaled_attenuation / 100.0, | |
3515 | min_db / 100.0, max_db / 100.0); | |
3516 | } | |
3a6297bc | 3517 | } else { |
f135d857 | 3518 | snprintf(dv, 127, "%.2f,%.2f,%.2f,%.2f", airplay_volume, 0.0, 0.0, 0.0); |
3a6297bc | 3519 | } |
ca562872 | 3520 | send_ssnc_metadata('pvol', dv, strlen(dv), 1); |
b59dd422 MB |
3521 | #endif |
3522 | ||
3a6297bc MB |
3523 | if (config.output->mute) |
3524 | config.output->mute(0); | |
3525 | conn->software_mute_enabled = 0; | |
3526 | ||
3527 | debug(2, | |
97ecff93 MB |
3528 | "player_volume_without_notification: volume mode is %d, airplay volume is %.2f, " |
3529 | "software_attenuation dB: %.2f, hardware_attenuation dB: %.2f, muting " | |
3a6297bc | 3530 | "is disabled.", |
97ecff93 | 3531 | volume_mode, airplay_volume, software_attenuation / 100.0, hardware_attenuation / 100.0); |
3a6297bc | 3532 | } |
b59dd422 | 3533 | // here, store the volume for possible use in the future |
1637a79d | 3534 | config.airplay_volume = airplay_volume; |
8201903a | 3535 | conn->own_airplay_volume = airplay_volume; |
601ac4d7 | 3536 | debug_mutex_unlock(&conn->volume_control_mutex, 3); |
a2fb5d21 | 3537 | } |
7187b63e | 3538 | |
1e07e1e0 | 3539 | void player_volume(double airplay_volume, rtsp_conn_info *conn) { |
d343a851 | 3540 | command_set_volume(airplay_volume); |
1e07e1e0 MB |
3541 | player_volume_without_notification(airplay_volume, conn); |
3542 | } | |
3543 | ||
de071aef | 3544 | void do_flush(uint32_t timestamp, rtsp_conn_info *conn) { |
c2e3fa5a | 3545 | |
829ea399 | 3546 | debug(3, "do_flush: flush to %u.", timestamp); |
18b37ea2 | 3547 | debug_mutex_lock(&conn->flush_mutex, 1000, 1); |
6f8c9e9a | 3548 | conn->flush_requested = 1; |
320baa4d | 3549 | conn->flush_rtp_timestamp = timestamp; // flush all packets up to, but not including, this one. |
3cb359c7 | 3550 | reset_input_flow_metrics(conn); |
c2e3fa5a | 3551 | debug_mutex_unlock(&conn->flush_mutex, 3); |
8f34c181 | 3552 | } |
c2e3fa5a | 3553 | |
8f34c181 MB |
3554 | void player_flush(uint32_t timestamp, rtsp_conn_info *conn) { |
3555 | debug(3, "player_flush"); | |
3556 | do_flush(timestamp, conn); | |
75f3f912 | 3557 | #ifdef CONFIG_METADATA |
a68f28ac | 3558 | // only send a flush metadata message if the first packet has been seen -- it's a bogus message |
bdfb1c6e MB |
3559 | // otherwise |
3560 | if (conn->first_packet_timestamp) { | |
bdfb1c6e MB |
3561 | char numbuf[32]; |
3562 | snprintf(numbuf, sizeof(numbuf), "%u", timestamp); | |
3563 | send_ssnc_metadata('pfls', numbuf, strlen(numbuf), 1); // contains cancellation points | |
3564 | } | |
75f3f912 | 3565 | #endif |
6f8c9e9a MB |
3566 | } |
3567 | ||
1464c4ed | 3568 | /* |
bdfb1c6e | 3569 | void player_full_flush(rtsp_conn_info *conn) { |
3f779949 | 3570 | debug(3, "player_full_flush"); |
bdfb1c6e MB |
3571 | // this basically flushes everything from the player |
3572 | // here, find the rtptime of the last from in the buffer and add 1 to it | |
3573 | // so as to ask to flush everything | |
3574 | int flush_needed = 0; | |
3575 | uint32_t rtpTimestamp; | |
3576 | debug_mutex_lock(&conn->ab_mutex, 30000, 0); | |
3577 | if ((conn->ab_synced != 0) && (conn->ab_write != conn->ab_read)) { | |
3578 | abuf_t *abuf = NULL; | |
3579 | seq_t last_seqno_written; | |
3580 | do { | |
3581 | last_seqno_written = conn->ab_write - 1; | |
3582 | abuf = conn->audio_buffer + BUFIDX(last_seqno_written); | |
3583 | } while ((abuf->ready == 0) && (last_seqno_written != conn->ab_read)); | |
3584 | if ((abuf != NULL) && (abuf->ready != 0)) { | |
bdfb1c6e | 3585 | rtpTimestamp = abuf->given_timestamp + abuf->length + 1; |
2986b282 | 3586 | debug(2, "full flush needed to %u", rtpTimestamp); |
bdfb1c6e MB |
3587 | flush_needed = 1; |
3588 | } else { | |
3589 | debug(2, "full flush not needed"); | |
3590 | } | |
3591 | } else { | |
3592 | debug(2, "full flush not needed -- buffers empty or not synced"); | |
3593 | } | |
3594 | debug_mutex_unlock(&conn->ab_mutex, 0); | |
3595 | if (flush_needed) | |
3596 | player_flush(rtpTimestamp, conn); | |
3597 | } | |
1464c4ed | 3598 | */ |
bdfb1c6e | 3599 | |
1464c4ed MB |
3600 | // perpare_to_play and play are split so that we can get the capabilities of the |
3601 | // dac etc. before initialising any decoders etc. | |
3602 | // for example, if we have 32-bit DACs, we can ask for 32 bit decodes | |
3603 | ||
3604 | int player_prepare_to_play(rtsp_conn_info *conn) { | |
6f8c9e9a | 3605 | // need to use conn in place of stream below. Need to put the stream as a parameter to he |
3001f39b | 3606 | if (conn->player_thread != NULL) |
06fa3485 | 3607 | die("Trying to create a second player thread for this RTSP session"); |
771aa1a1 | 3608 | if (config.buffer_start_fill > BUFFER_FRAMES) |
87a0475c MB |
3609 | die("specified buffer starting fill %d > buffer size %d", config.buffer_start_fill, |
3610 | BUFFER_FRAMES); | |
7b8e6865 | 3611 | // active, and should be before play's command hook, command_start() |
60b3a6f7 | 3612 | command_start(); |
d4ea91aa | 3613 | conn->input_bytes_per_frame = 4; // default -- may be changed later |
83c0405d MB |
3614 | // call on the output device to prepare itself |
3615 | if ((config.output) && (config.output->prepare)) | |
c8b0be30 | 3616 | config.output->prepare(); |
1464c4ed MB |
3617 | return 0; |
3618 | } | |
c8b0be30 | 3619 | |
1464c4ed | 3620 | int player_play(rtsp_conn_info *conn) { |
986f9587 MB |
3621 | debug(2, "Connection %d: player_play.", conn->connection_number); |
3622 | pthread_cleanup_debug_mutex_lock(&conn->player_create_delete_mutex, 5000, 1); | |
3623 | if (conn->player_thread == NULL) { | |
3624 | pthread_t *pt = malloc(sizeof(pthread_t)); | |
3625 | if (pt == NULL) | |
3626 | die("Couldn't allocate space for pthread_t"); | |
3627 | int rc = pthread_create(pt, NULL, player_thread_func, (void *)conn); | |
3628 | if (rc) | |
3629 | debug(1, "Connection %d: error creating player_thread: %s", conn->connection_number, | |
3630 | strerror(errno)); | |
3631 | conn->player_thread = pt; // set _after_ creation of thread | |
3632 | } else { | |
3633 | debug(1, "Connection %d: player thread already exists.", conn->connection_number); | |
3634 | } | |
3635 | pthread_cleanup_pop(1); // release the player_create_delete_mutex | |
58a66ebb | 3636 | #ifdef CONFIG_METADATA |
58a66ebb MB |
3637 | send_ssnc_metadata('pbeg', NULL, 0, 1); // contains cancellation points |
3638 | #endif | |
771aa1a1 | 3639 | return 0; |
a2fb5d21 JL |
3640 | } |
3641 | ||
418b1ba7 | 3642 | int player_stop(rtsp_conn_info *conn) { |
ebacd7f3 | 3643 | // note -- this may be called from another connection thread. |
986f9587 MB |
3644 | debug(2, "Connection %d: player_stop.", conn->connection_number); |
3645 | int response = 0; // okay | |
3646 | pthread_cleanup_debug_mutex_lock(&conn->player_create_delete_mutex, 5000, 1); | |
3647 | pthread_t *pt = conn->player_thread; | |
3648 | if (pt) { | |
4046c0e7 | 3649 | debug(3, "player_thread cancel..."); |
986f9587 MB |
3650 | conn->player_thread = NULL; // cleared _before_ cancelling of thread |
3651 | pthread_cancel(*pt); | |
4046c0e7 | 3652 | debug(3, "player_thread join..."); |
986f9587 | 3653 | if (pthread_join(*pt, NULL) == -1) { |
2737222b MB |
3654 | char errorstring[1024]; |
3655 | strerror_r(errno, (char *)errorstring, sizeof(errorstring)); | |
3656 | debug(1, "Connection %d: error %d joining player thread: \"%s\".", conn->connection_number, | |
3657 | errno, (char *)errorstring); | |
3658 | } else { | |
986f9587 | 3659 | debug(2, "Connection %d: player_stop successful.", conn->connection_number); |
2737222b | 3660 | } |
986f9587 MB |
3661 | free(pt); |
3662 | response = 0; // deleted | |
3663 | } else { | |
3664 | debug(2, "Connection %d: no player thread.", conn->connection_number); | |
3665 | response = -1; // already deleted or never created... | |
3666 | } | |
3667 | pthread_cleanup_pop(1); // release the player_create_delete_mutex | |
3668 | if (response == 0) { // if the thread was just stopped and deleted... | |
3669 | #ifdef CONFIG_AIRPLAY_2 | |
3670 | ptp_send_control_message_string("E"); // signify play is "E"nding | |
3671 | #endif | |
064bd293 | 3672 | #ifdef CONFIG_METADATA |
bae7585c | 3673 | send_ssnc_metadata('pend', NULL, 0, 1); // contains cancellation points |
064bd293 | 3674 | #endif |
3001f39b | 3675 | command_stop(); |
15ba7324 | 3676 | } |
986f9587 | 3677 | return response; |
6f8b35d1 | 3678 | } |