audio-io.c 21 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817
  1. /******************************************************************************
  2. Copyright (C) 2013 by Hugh Bailey <[email protected]>
  3. This program is free software: you can redistribute it and/or modify
  4. it under the terms of the GNU General Public License as published by
  5. the Free Software Foundation, either version 2 of the License, or
  6. (at your option) any later version.
  7. This program is distributed in the hope that it will be useful,
  8. but WITHOUT ANY WARRANTY; without even the implied warranty of
  9. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  10. GNU General Public License for more details.
  11. You should have received a copy of the GNU General Public License
  12. along with this program. If not, see <http://www.gnu.org/licenses/>.
  13. ******************************************************************************/
  14. #include <math.h>
  15. #include <inttypes.h>
  16. #include "../util/threading.h"
  17. #include "../util/darray.h"
  18. #include "../util/circlebuf.h"
  19. #include "../util/platform.h"
  20. #include "audio-io.h"
  21. #include "audio-resampler.h"
  22. /* #define DEBUG_AUDIO */
  23. #define nop() do {int invalid = 0;} while(0)
  24. struct audio_input {
  25. struct audio_convert_info conversion;
  26. audio_resampler_t *resampler;
  27. audio_output_callback_t callback;
  28. void *param;
  29. };
  30. static inline void audio_input_free(struct audio_input *input)
  31. {
  32. audio_resampler_destroy(input->resampler);
  33. }
  34. struct audio_line {
  35. char *name;
  36. struct audio_output *audio;
  37. struct circlebuf buffers[MAX_AV_PLANES];
  38. pthread_mutex_t mutex;
  39. DARRAY(uint8_t) volume_buffers[MAX_AV_PLANES];
  40. uint64_t base_timestamp;
  41. uint64_t last_timestamp;
  42. uint64_t next_ts_min;
  43. /* specifies which mixes this line applies to via bits */
  44. uint32_t mixers;
  45. /* states whether this line is still being used. if not, then when the
  46. * buffer is depleted, it's destroyed */
  47. bool alive;
  48. struct audio_line **prev_next;
  49. struct audio_line *next;
  50. };
  51. static inline void audio_line_destroy_data(struct audio_line *line)
  52. {
  53. for (size_t i = 0; i < MAX_AV_PLANES; i++) {
  54. circlebuf_free(&line->buffers[i]);
  55. da_free(line->volume_buffers[i]);
  56. }
  57. pthread_mutex_destroy(&line->mutex);
  58. bfree(line->name);
  59. bfree(line);
  60. }
  61. struct audio_mix {
  62. DARRAY(struct audio_input) inputs;
  63. DARRAY(uint8_t) mix_buffers[MAX_AV_PLANES];
  64. };
  65. struct audio_output {
  66. struct audio_output_info info;
  67. size_t block_size;
  68. size_t channels;
  69. size_t planes;
  70. pthread_t thread;
  71. os_event_t *stop_event;
  72. bool initialized;
  73. pthread_mutex_t line_mutex;
  74. struct audio_line *first_line;
  75. pthread_mutex_t input_mutex;
  76. struct audio_mix mixes[MAX_AUDIO_MIXES];
  77. };
  78. static inline void audio_output_removeline(struct audio_output *audio,
  79. struct audio_line *line)
  80. {
  81. pthread_mutex_lock(&audio->line_mutex);
  82. if (line->prev_next)
  83. *line->prev_next = line->next;
  84. if (line->next)
  85. line->next->prev_next = line->prev_next;
  86. pthread_mutex_unlock(&audio->line_mutex);
  87. audio_line_destroy_data(line);
  88. }
  89. /* ------------------------------------------------------------------------- */
  90. /* the following functions are used to calculate frame offsets based upon
  91. * timestamps. this will actually work accurately as long as you handle the
  92. * values correctly */
  93. static inline double ts_to_frames(const audio_t *audio, uint64_t ts)
  94. {
  95. double audio_offset_d = (double)ts;
  96. audio_offset_d /= 1000000000.0;
  97. audio_offset_d *= (double)audio->info.samples_per_sec;
  98. return audio_offset_d;
  99. }
  100. static inline double positive_round(double val)
  101. {
  102. return floor(val+0.5);
  103. }
  104. static size_t ts_diff_frames(const audio_t *audio, uint64_t ts1, uint64_t ts2)
  105. {
  106. double diff = ts_to_frames(audio, ts1) - ts_to_frames(audio, ts2);
  107. return (size_t)positive_round(diff);
  108. }
  109. static size_t ts_diff_bytes(const audio_t *audio, uint64_t ts1, uint64_t ts2)
  110. {
  111. return ts_diff_frames(audio, ts1, ts2) * audio->block_size;
  112. }
  113. /* unless the value is 3+ hours worth of frames, this won't overflow */
  114. static inline uint64_t conv_frames_to_time(const audio_t *audio,
  115. uint32_t frames)
  116. {
  117. return (uint64_t)frames * 1000000000ULL /
  118. (uint64_t)audio->info.samples_per_sec;
  119. }
  120. /* ------------------------------------------------------------------------- */
  121. /* this only really happens with the very initial data insertion. can be
  122. * ignored safely. */
  123. static inline void clear_excess_audio_data(struct audio_line *line,
  124. uint64_t prev_time)
  125. {
  126. size_t size = ts_diff_bytes(line->audio, prev_time,
  127. line->base_timestamp);
  128. /*blog(LOG_DEBUG, "Excess audio data for audio line '%s', somehow "
  129. "audio data went back in time by %"PRIu32" bytes. "
  130. "prev_time: %"PRIu64", line->base_timestamp: %"PRIu64,
  131. line->name, (uint32_t)size,
  132. prev_time, line->base_timestamp);*/
  133. for (size_t i = 0; i < line->audio->planes; i++) {
  134. size_t clear_size = (size < line->buffers[i].size) ?
  135. size : line->buffers[i].size;
  136. circlebuf_pop_front(&line->buffers[i], NULL, clear_size);
  137. }
  138. }
  139. static inline uint64_t min_uint64(uint64_t a, uint64_t b)
  140. {
  141. return a < b ? a : b;
  142. }
  143. static inline size_t min_size(size_t a, size_t b)
  144. {
  145. return a < b ? a : b;
  146. }
  147. #ifndef CLAMP
  148. #define CLAMP(val, minval, maxval) \
  149. ((val > maxval) ? maxval : ((val < minval) ? minval : val))
  150. #endif
  151. #define MIX_BUFFER_SIZE 256
  152. /* TODO: optimize mixing */
  153. static void mix_float(struct audio_output *audio, struct audio_line *line,
  154. size_t size, size_t time_offset, size_t plane)
  155. {
  156. float *mixes[MAX_AUDIO_MIXES];
  157. float vals[MIX_BUFFER_SIZE];
  158. for (size_t mix_idx = 0; mix_idx < MAX_AUDIO_MIXES; mix_idx++) {
  159. uint8_t *bytes = audio->mixes[mix_idx].mix_buffers[plane].array;
  160. mixes[mix_idx] = (float*)&bytes[time_offset];
  161. }
  162. while (size) {
  163. size_t pop_count = min_size(size, sizeof(vals));
  164. size -= pop_count;
  165. circlebuf_pop_front(&line->buffers[plane], vals, pop_count);
  166. pop_count /= sizeof(float);
  167. for (size_t mix_idx = 0; mix_idx < MAX_AUDIO_MIXES; mix_idx++) {
  168. /* only include this audio line in this mix if it's set
  169. * via the line's 'mixes' variable */
  170. if ((line->mixers & (1 << mix_idx)) == 0)
  171. continue;
  172. for (size_t i = 0; i < pop_count; i++) {
  173. *(mixes[mix_idx]++) += vals[i];
  174. }
  175. }
  176. }
  177. }
  178. static inline bool mix_audio_line(struct audio_output *audio,
  179. struct audio_line *line, size_t size, uint64_t timestamp)
  180. {
  181. size_t time_offset = ts_diff_bytes(audio,
  182. line->base_timestamp, timestamp);
  183. if (time_offset > size)
  184. return false;
  185. size -= time_offset;
  186. #ifdef DEBUG_AUDIO
  187. blog(LOG_DEBUG, "shaved off %lu bytes", size);
  188. #endif
  189. for (size_t i = 0; i < audio->planes; i++) {
  190. size_t pop_size = min_size(size, line->buffers[i].size);
  191. mix_float(audio, line, pop_size, time_offset, i);
  192. }
  193. return true;
  194. }
  195. static bool resample_audio_output(struct audio_input *input,
  196. struct audio_data *data)
  197. {
  198. bool success = true;
  199. if (input->resampler) {
  200. uint8_t *output[MAX_AV_PLANES];
  201. uint32_t frames;
  202. uint64_t offset;
  203. memset(output, 0, sizeof(output));
  204. success = audio_resampler_resample(input->resampler,
  205. output, &frames, &offset,
  206. (const uint8_t *const *)data->data,
  207. data->frames);
  208. for (size_t i = 0; i < MAX_AV_PLANES; i++)
  209. data->data[i] = output[i];
  210. data->frames = frames;
  211. data->timestamp -= offset;
  212. }
  213. return success;
  214. }
  215. static inline void do_audio_output(struct audio_output *audio,
  216. size_t mix_idx, uint64_t timestamp, uint32_t frames)
  217. {
  218. struct audio_mix *mix = &audio->mixes[mix_idx];
  219. struct audio_data data;
  220. for (size_t i = 0; i < MAX_AV_PLANES; i++)
  221. data.data[i] = mix->mix_buffers[i].array;
  222. data.frames = frames;
  223. data.timestamp = timestamp;
  224. data.volume = 1.0f;
  225. pthread_mutex_lock(&audio->input_mutex);
  226. for (size_t i = 0; i < mix->inputs.num; i++) {
  227. struct audio_input *input = mix->inputs.array+i;
  228. if (resample_audio_output(input, &data))
  229. input->callback(input->param, mix_idx, &data);
  230. }
  231. pthread_mutex_unlock(&audio->input_mutex);
  232. }
  233. static inline void clamp_audio_output(struct audio_output *audio, size_t bytes)
  234. {
  235. size_t float_size = bytes / sizeof(float);
  236. for (size_t mix_idx = 0; mix_idx < MAX_AUDIO_MIXES; mix_idx++) {
  237. struct audio_mix *mix = &audio->mixes[mix_idx];
  238. /* do not process mixing if a specific mix is inactive */
  239. if (!mix->inputs.num)
  240. continue;
  241. for (size_t plane = 0; plane < audio->planes; plane++) {
  242. float *mix_data = (float*)mix->mix_buffers[plane].array;
  243. float *mix_end = &mix_data[float_size];
  244. while (mix_data < mix_end) {
  245. float val = *mix_data;
  246. val = (val > 1.0f) ? 1.0f : val;
  247. val = (val < -1.0f) ? -1.0f : val;
  248. *(mix_data++) = val;
  249. }
  250. }
  251. }
  252. }
  253. static uint64_t mix_and_output(struct audio_output *audio, uint64_t audio_time,
  254. uint64_t prev_time)
  255. {
  256. struct audio_line *line = audio->first_line;
  257. uint32_t frames = (uint32_t)ts_diff_frames(audio, audio_time,
  258. prev_time);
  259. size_t bytes = frames * audio->block_size;
  260. #ifdef DEBUG_AUDIO
  261. blog(LOG_DEBUG, "audio_time: %llu, prev_time: %llu, bytes: %lu",
  262. audio_time, prev_time, bytes);
  263. #endif
  264. /* return an adjusted audio_time according to the amount
  265. * of data that was sampled to ensure seamless transmission */
  266. audio_time = prev_time + conv_frames_to_time(audio, frames);
  267. /* resize and clear mix buffers */
  268. for (size_t mix_idx = 0; mix_idx < MAX_AUDIO_MIXES; mix_idx++) {
  269. struct audio_mix *mix = &audio->mixes[mix_idx];
  270. for (size_t i = 0; i < audio->planes; i++) {
  271. da_resize(mix->mix_buffers[i], bytes);
  272. memset(mix->mix_buffers[i].array, 0, bytes);
  273. }
  274. }
  275. /* mix audio lines */
  276. while (line) {
  277. struct audio_line *next = line->next;
  278. /* if line marked for removal, destroy and move to the next */
  279. if (!line->buffers[0].size) {
  280. if (!line->alive) {
  281. audio_output_removeline(audio, line);
  282. line = next;
  283. continue;
  284. }
  285. }
  286. pthread_mutex_lock(&line->mutex);
  287. if (line->buffers[0].size && line->base_timestamp < prev_time) {
  288. clear_excess_audio_data(line, prev_time);
  289. line->base_timestamp = prev_time;
  290. }
  291. if (mix_audio_line(audio, line, bytes, prev_time))
  292. line->base_timestamp = audio_time;
  293. pthread_mutex_unlock(&line->mutex);
  294. line = next;
  295. }
  296. /* clamps audio data to -1.0..1.0 */
  297. clamp_audio_output(audio, bytes);
  298. /* output */
  299. for (size_t i = 0; i < MAX_AUDIO_MIXES; i++)
  300. do_audio_output(audio, i, prev_time, frames);
  301. return audio_time;
  302. }
  303. /* sample audio 40 times a second */
  304. #define AUDIO_WAIT_TIME (1000/40)
  305. static void *audio_thread(void *param)
  306. {
  307. struct audio_output *audio = param;
  308. uint64_t buffer_time = audio->info.buffer_ms * 1000000;
  309. uint64_t prev_time = os_gettime_ns() - buffer_time;
  310. uint64_t audio_time;
  311. os_set_thread_name("audio-io: audio thread");
  312. while (os_event_try(audio->stop_event) == EAGAIN) {
  313. os_sleep_ms(AUDIO_WAIT_TIME);
  314. pthread_mutex_lock(&audio->line_mutex);
  315. audio_time = os_gettime_ns() - buffer_time;
  316. audio_time = mix_and_output(audio, audio_time, prev_time);
  317. prev_time = audio_time;
  318. pthread_mutex_unlock(&audio->line_mutex);
  319. }
  320. return NULL;
  321. }
  322. /* ------------------------------------------------------------------------- */
  323. static size_t audio_get_input_idx(const audio_t *audio, size_t mix_idx,
  324. audio_output_callback_t callback, void *param)
  325. {
  326. const struct audio_mix *mix = &audio->mixes[mix_idx];
  327. for (size_t i = 0; i < mix->inputs.num; i++) {
  328. struct audio_input *input = mix->inputs.array+i;
  329. if (input->callback == callback && input->param == param)
  330. return i;
  331. }
  332. return DARRAY_INVALID;
  333. }
  334. static inline bool audio_input_init(struct audio_input *input,
  335. struct audio_output *audio)
  336. {
  337. if (input->conversion.format != audio->info.format ||
  338. input->conversion.samples_per_sec != audio->info.samples_per_sec ||
  339. input->conversion.speakers != audio->info.speakers) {
  340. struct resample_info from = {
  341. .format = audio->info.format,
  342. .samples_per_sec = audio->info.samples_per_sec,
  343. .speakers = audio->info.speakers
  344. };
  345. struct resample_info to = {
  346. .format = input->conversion.format,
  347. .samples_per_sec = input->conversion.samples_per_sec,
  348. .speakers = input->conversion.speakers
  349. };
  350. input->resampler = audio_resampler_create(&to, &from);
  351. if (!input->resampler) {
  352. blog(LOG_ERROR, "audio_input_init: Failed to "
  353. "create resampler");
  354. return false;
  355. }
  356. } else {
  357. input->resampler = NULL;
  358. }
  359. return true;
  360. }
  361. bool audio_output_connect(audio_t *audio, size_t mi,
  362. const struct audio_convert_info *conversion,
  363. audio_output_callback_t callback, void *param)
  364. {
  365. bool success = false;
  366. if (!audio || mi >= MAX_AUDIO_MIXES) return false;
  367. pthread_mutex_lock(&audio->input_mutex);
  368. if (audio_get_input_idx(audio, mi, callback, param) == DARRAY_INVALID) {
  369. struct audio_mix *mix = &audio->mixes[mi];
  370. struct audio_input input;
  371. input.callback = callback;
  372. input.param = param;
  373. if (conversion) {
  374. input.conversion = *conversion;
  375. } else {
  376. input.conversion.format = audio->info.format;
  377. input.conversion.speakers = audio->info.speakers;
  378. input.conversion.samples_per_sec =
  379. audio->info.samples_per_sec;
  380. }
  381. if (input.conversion.format == AUDIO_FORMAT_UNKNOWN)
  382. input.conversion.format = audio->info.format;
  383. if (input.conversion.speakers == SPEAKERS_UNKNOWN)
  384. input.conversion.speakers = audio->info.speakers;
  385. if (input.conversion.samples_per_sec == 0)
  386. input.conversion.samples_per_sec =
  387. audio->info.samples_per_sec;
  388. success = audio_input_init(&input, audio);
  389. if (success)
  390. da_push_back(mix->inputs, &input);
  391. }
  392. pthread_mutex_unlock(&audio->input_mutex);
  393. return success;
  394. }
  395. void audio_output_disconnect(audio_t *audio, size_t mix_idx,
  396. audio_output_callback_t callback, void *param)
  397. {
  398. if (!audio || mix_idx >= MAX_AUDIO_MIXES) return;
  399. pthread_mutex_lock(&audio->input_mutex);
  400. size_t idx = audio_get_input_idx(audio, mix_idx, callback, param);
  401. if (idx != DARRAY_INVALID) {
  402. struct audio_mix *mix = &audio->mixes[mix_idx];
  403. audio_input_free(mix->inputs.array+idx);
  404. da_erase(mix->inputs, idx);
  405. }
  406. pthread_mutex_unlock(&audio->input_mutex);
  407. }
  408. static inline bool valid_audio_params(const struct audio_output_info *info)
  409. {
  410. return info->format && info->name && info->samples_per_sec > 0 &&
  411. info->speakers > 0;
  412. }
  413. int audio_output_open(audio_t **audio, struct audio_output_info *info)
  414. {
  415. struct audio_output *out;
  416. pthread_mutexattr_t attr;
  417. bool planar = is_audio_planar(info->format);
  418. if (!valid_audio_params(info))
  419. return AUDIO_OUTPUT_INVALIDPARAM;
  420. out = bzalloc(sizeof(struct audio_output));
  421. if (!out)
  422. goto fail;
  423. memcpy(&out->info, info, sizeof(struct audio_output_info));
  424. pthread_mutex_init_value(&out->line_mutex);
  425. out->channels = get_audio_channels(info->speakers);
  426. out->planes = planar ? out->channels : 1;
  427. out->block_size = (planar ? 1 : out->channels) *
  428. get_audio_bytes_per_channel(info->format);
  429. if (pthread_mutexattr_init(&attr) != 0)
  430. goto fail;
  431. if (pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE) != 0)
  432. goto fail;
  433. if (pthread_mutex_init(&out->line_mutex, &attr) != 0)
  434. goto fail;
  435. if (pthread_mutex_init(&out->input_mutex, NULL) != 0)
  436. goto fail;
  437. if (os_event_init(&out->stop_event, OS_EVENT_TYPE_MANUAL) != 0)
  438. goto fail;
  439. if (pthread_create(&out->thread, NULL, audio_thread, out) != 0)
  440. goto fail;
  441. out->initialized = true;
  442. *audio = out;
  443. return AUDIO_OUTPUT_SUCCESS;
  444. fail:
  445. audio_output_close(out);
  446. return AUDIO_OUTPUT_FAIL;
  447. }
  448. void audio_output_close(audio_t *audio)
  449. {
  450. void *thread_ret;
  451. struct audio_line *line;
  452. if (!audio)
  453. return;
  454. if (audio->initialized) {
  455. os_event_signal(audio->stop_event);
  456. pthread_join(audio->thread, &thread_ret);
  457. }
  458. line = audio->first_line;
  459. while (line) {
  460. struct audio_line *next = line->next;
  461. audio_line_destroy_data(line);
  462. line = next;
  463. }
  464. for (size_t mix_idx = 0; mix_idx < MAX_AUDIO_MIXES; mix_idx++) {
  465. struct audio_mix *mix = &audio->mixes[mix_idx];
  466. for (size_t i = 0; i < mix->inputs.num; i++)
  467. audio_input_free(mix->inputs.array+i);
  468. for (size_t i = 0; i < MAX_AV_PLANES; i++)
  469. da_free(mix->mix_buffers[i]);
  470. da_free(mix->inputs);
  471. }
  472. os_event_destroy(audio->stop_event);
  473. pthread_mutex_destroy(&audio->line_mutex);
  474. bfree(audio);
  475. }
  476. audio_line_t *audio_output_create_line(audio_t *audio, const char *name,
  477. uint32_t mixers)
  478. {
  479. if (!audio) return NULL;
  480. struct audio_line *line = bzalloc(sizeof(struct audio_line));
  481. line->alive = true;
  482. line->audio = audio;
  483. line->mixers = mixers;
  484. if (pthread_mutex_init(&line->mutex, NULL) != 0) {
  485. blog(LOG_ERROR, "audio_output_createline: Failed to create "
  486. "mutex");
  487. bfree(line);
  488. return NULL;
  489. }
  490. pthread_mutex_lock(&audio->line_mutex);
  491. if (audio->first_line) {
  492. audio->first_line->prev_next = &line->next;
  493. line->next = audio->first_line;
  494. }
  495. line->prev_next = &audio->first_line;
  496. audio->first_line = line;
  497. pthread_mutex_unlock(&audio->line_mutex);
  498. line->name = bstrdup(name ? name : "(unnamed audio line)");
  499. return line;
  500. }
  501. const struct audio_output_info *audio_output_get_info(const audio_t *audio)
  502. {
  503. return audio ? &audio->info : NULL;
  504. }
  505. void audio_line_destroy(struct audio_line *line)
  506. {
  507. if (line) {
  508. if (!line->buffers[0].size)
  509. audio_output_removeline(line->audio, line);
  510. else
  511. line->alive = false;
  512. }
  513. }
  514. bool audio_output_active(const audio_t *audio)
  515. {
  516. if (!audio) return false;
  517. for (size_t mix_idx = 0; mix_idx < MAX_AUDIO_MIXES; mix_idx++) {
  518. const struct audio_mix *mix = &audio->mixes[mix_idx];
  519. if (mix->inputs.num != 0)
  520. return true;
  521. }
  522. return false;
  523. }
  524. size_t audio_output_get_block_size(const audio_t *audio)
  525. {
  526. return audio ? audio->block_size : 0;
  527. }
  528. size_t audio_output_get_planes(const audio_t *audio)
  529. {
  530. return audio ? audio->planes : 0;
  531. }
  532. size_t audio_output_get_channels(const audio_t *audio)
  533. {
  534. return audio ? audio->channels : 0;
  535. }
  536. uint32_t audio_output_get_sample_rate(const audio_t *audio)
  537. {
  538. return audio ? audio->info.samples_per_sec : 0;
  539. }
  540. /* TODO: optimize these two functions */
  541. static inline void mul_vol_float(float *array, float volume, size_t count)
  542. {
  543. for (size_t i = 0; i < count; i++)
  544. array[i] *= volume;
  545. }
  546. static void audio_line_place_data_pos(struct audio_line *line,
  547. const struct audio_data *data, size_t position)
  548. {
  549. bool planar = line->audio->planes > 1;
  550. size_t total_num = data->frames * (planar ? 1 : line->audio->channels);
  551. size_t total_size = data->frames * line->audio->block_size;
  552. for (size_t i = 0; i < line->audio->planes; i++) {
  553. da_copy_array(line->volume_buffers[i], data->data[i],
  554. total_size);
  555. uint8_t *array = line->volume_buffers[i].array;
  556. switch (line->audio->info.format) {
  557. case AUDIO_FORMAT_FLOAT:
  558. case AUDIO_FORMAT_FLOAT_PLANAR:
  559. mul_vol_float((float*)array, data->volume, total_num);
  560. break;
  561. default:
  562. blog(LOG_ERROR, "audio_line_place_data_pos: "
  563. "Unsupported or unknown format");
  564. break;
  565. }
  566. circlebuf_place(&line->buffers[i], position,
  567. line->volume_buffers[i].array, total_size);
  568. }
  569. }
  570. static inline uint64_t smooth_ts(struct audio_line *line, uint64_t timestamp)
  571. {
  572. if (!line->next_ts_min)
  573. return timestamp;
  574. bool ts_under = (timestamp < line->next_ts_min);
  575. uint64_t diff = ts_under ?
  576. (line->next_ts_min - timestamp) :
  577. (timestamp - line->next_ts_min);
  578. #ifdef DEBUG_AUDIO
  579. if (diff >= TS_SMOOTHING_THRESHOLD)
  580. blog(LOG_DEBUG, "above TS smoothing threshold by %"PRIu64,
  581. diff);
  582. #endif
  583. return (diff < TS_SMOOTHING_THRESHOLD) ? line->next_ts_min : timestamp;
  584. }
  585. static void audio_line_place_data(struct audio_line *line,
  586. const struct audio_data *data)
  587. {
  588. size_t pos;
  589. uint64_t timestamp = smooth_ts(line, data->timestamp);
  590. pos = ts_diff_bytes(line->audio, timestamp, line->base_timestamp);
  591. line->next_ts_min =
  592. timestamp + conv_frames_to_time(line->audio, data->frames);
  593. #ifdef DEBUG_AUDIO
  594. blog(LOG_DEBUG, "data->timestamp: %llu, line->base_timestamp: %llu, "
  595. "pos: %lu, bytes: %lu, buf size: %lu",
  596. timestamp, line->base_timestamp, pos,
  597. data->frames * line->audio->block_size,
  598. line->buffers[0].size);
  599. #endif
  600. audio_line_place_data_pos(line, data, pos);
  601. }
  602. #define MAX_DELAY_NS 6000000000ULL
  603. /* prevent insertation of data too far away from expected audio timing */
  604. static inline bool valid_timestamp_range(struct audio_line *line, uint64_t ts)
  605. {
  606. uint64_t buffer_ns = 1000000ULL * line->audio->info.buffer_ms;
  607. uint64_t max_ts = line->base_timestamp + buffer_ns + MAX_DELAY_NS;
  608. return ts >= line->base_timestamp && ts < max_ts;
  609. }
  610. void audio_line_output(audio_line_t *line, const struct audio_data *data)
  611. {
  612. if (!line || !data) return;
  613. pthread_mutex_lock(&line->mutex);
  614. if (!line->buffers[0].size) {
  615. line->base_timestamp = data->timestamp -
  616. line->audio->info.buffer_ms * 1000000;
  617. audio_line_place_data(line, data);
  618. } else if (valid_timestamp_range(line, data->timestamp)) {
  619. audio_line_place_data(line, data);
  620. } else {
  621. blog(LOG_DEBUG, "Bad timestamp for audio line '%s', "
  622. "data->timestamp: %"PRIu64", "
  623. "line->base_timestamp: %"PRIu64". This can "
  624. "sometimes happen when there's a pause in "
  625. "the threads.", line->name, data->timestamp,
  626. line->base_timestamp);
  627. }
  628. pthread_mutex_unlock(&line->mutex);
  629. }
  630. void audio_line_set_mixers(audio_line_t *line, uint32_t mixers)
  631. {
  632. if (!!line)
  633. line->mixers = mixers;
  634. }
  635. uint32_t audio_line_get_mixers(audio_line_t *line)
  636. {
  637. return !!line ? line->mixers : 0;
  638. }