audio-io.c 23 KB

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