audio-io.c 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533
  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 "../util/threading.h"
  15. #include "../util/darray.h"
  16. #include "../util/circlebuf.h"
  17. #include "../util/platform.h"
  18. #include "audio-io.h"
  19. struct audio_input {
  20. struct audio_convert_info conversion;
  21. void (*callback)(void *param, const struct audio_data *data);
  22. void *param;
  23. };
  24. struct audio_line {
  25. char *name;
  26. struct audio_output *audio;
  27. struct circlebuf buffer;
  28. pthread_mutex_t mutex;
  29. DARRAY(uint8_t) volume_buffer;
  30. uint64_t base_timestamp;
  31. uint64_t last_timestamp;
  32. /* states whether this line is still being used. if not, then when the
  33. * buffer is depleted, it's destroyed */
  34. bool alive;
  35. struct audio_line **prev_next;
  36. struct audio_line *next;
  37. };
  38. static inline void audio_line_destroy_data(struct audio_line *line)
  39. {
  40. circlebuf_free(&line->buffer);
  41. da_free(line->volume_buffer);
  42. pthread_mutex_destroy(&line->mutex);
  43. bfree(line->name);
  44. bfree(line);
  45. }
  46. struct audio_output {
  47. struct audio_output_info info;
  48. size_t block_size;
  49. size_t channels;
  50. pthread_t thread;
  51. event_t stop_event;
  52. DARRAY(uint8_t) pending_bytes;
  53. DARRAY(uint8_t) mix_buffer;
  54. bool initialized;
  55. pthread_mutex_t line_mutex;
  56. struct audio_line *first_line;
  57. pthread_mutex_t input_mutex;
  58. DARRAY(struct audio_input) inputs;
  59. };
  60. static inline void audio_output_removeline(struct audio_output *audio,
  61. struct audio_line *line)
  62. {
  63. pthread_mutex_lock(&audio->line_mutex);
  64. *line->prev_next = line->next;
  65. if (line->next)
  66. line->next->prev_next = line->prev_next;
  67. pthread_mutex_unlock(&audio->line_mutex);
  68. audio_line_destroy_data(line);
  69. }
  70. static inline uint32_t time_to_frames(audio_t audio, uint64_t offset)
  71. {
  72. double audio_offset_d = (double)offset;
  73. audio_offset_d /= 1000000000.0;
  74. audio_offset_d *= (double)audio->info.samples_per_sec;
  75. return (uint32_t)audio_offset_d;
  76. }
  77. static inline size_t time_to_bytes(audio_t audio, uint64_t offset)
  78. {
  79. return time_to_frames(audio, offset) * audio->block_size;
  80. }
  81. /* ------------------------------------------------------------------------- */
  82. static inline void clear_excess_audio_data(struct audio_line *line,
  83. uint64_t size)
  84. {
  85. if (size > line->buffer.size)
  86. size = line->buffer.size;
  87. blog(LOG_WARNING, "Excess audio data for audio line '%s', somehow "
  88. "audio data went back in time by %llu bytes",
  89. line->name, size);
  90. circlebuf_pop_front(&line->buffer, NULL, (size_t)size);
  91. }
  92. static inline uint64_t min_uint64(uint64_t a, uint64_t b)
  93. {
  94. return a < b ? a : b;
  95. }
  96. static inline void mix_audio_line(struct audio_output *audio,
  97. struct audio_line *line, size_t size, uint64_t timestamp)
  98. {
  99. /* TODO: this just overwrites, handle actual mixing */
  100. if (!line->buffer.size) {
  101. if (!line->alive)
  102. audio_output_removeline(audio, line);
  103. return;
  104. }
  105. size_t time_offset = time_to_bytes(audio,
  106. line->base_timestamp - timestamp);
  107. if (time_offset > size)
  108. return;
  109. size -= time_offset;
  110. size_t pop_size = (size_t)min_uint64(size, line->buffer.size);
  111. circlebuf_pop_front(&line->buffer,
  112. audio->mix_buffer.array + time_offset,
  113. pop_size);
  114. }
  115. static inline void do_audio_output(struct audio_output *audio,
  116. uint64_t timestamp, uint32_t frames)
  117. {
  118. struct audio_data data;
  119. data.data = audio->mix_buffer.array;
  120. data.frames = frames;
  121. data.timestamp = timestamp;
  122. data.volume = 1.0f;
  123. /* TODO: conversion */
  124. pthread_mutex_lock(&audio->input_mutex);
  125. for (size_t i = 0; i < audio->inputs.num; i++) {
  126. struct audio_input *input = audio->inputs.array+i;
  127. input->callback(input->param, &data);
  128. }
  129. pthread_mutex_unlock(&audio->input_mutex);
  130. }
  131. static void mix_and_output(struct audio_output *audio, uint64_t audio_time,
  132. uint64_t prev_time)
  133. {
  134. struct audio_line *line = audio->first_line;
  135. uint64_t time_offset = audio_time - prev_time;
  136. uint32_t frames = time_to_frames(audio, time_offset);
  137. size_t bytes = frames * audio->block_size;
  138. da_resize(audio->mix_buffer, bytes);
  139. memset(audio->mix_buffer.array, 0, bytes);
  140. while (line) {
  141. struct audio_line *next = line->next;
  142. if (line->buffer.size && line->base_timestamp < prev_time) {
  143. clear_excess_audio_data(line,
  144. prev_time - line->base_timestamp);
  145. line->base_timestamp = prev_time;
  146. }
  147. mix_audio_line(audio, line, bytes, prev_time);
  148. line->base_timestamp = audio_time;
  149. line = next;
  150. }
  151. do_audio_output(audio, prev_time, frames);
  152. }
  153. /* sample audio 40 times a second */
  154. #define AUDIO_WAIT_TIME (1000/40)
  155. static void *audio_thread(void *param)
  156. {
  157. struct audio_output *audio = param;
  158. uint64_t buffer_time = audio->info.buffer_ms * 1000000;
  159. uint64_t prev_time = os_gettime_ns() - buffer_time;
  160. uint64_t audio_time;
  161. while (event_try(&audio->stop_event) == EAGAIN) {
  162. os_sleep_ms(AUDIO_WAIT_TIME);
  163. pthread_mutex_lock(&audio->line_mutex);
  164. audio_time = os_gettime_ns() - buffer_time;
  165. mix_and_output(audio, audio_time, prev_time);
  166. prev_time = audio_time;
  167. pthread_mutex_unlock(&audio->line_mutex);
  168. }
  169. return NULL;
  170. }
  171. /* ------------------------------------------------------------------------- */
  172. static size_t audio_get_input_idx(audio_t video,
  173. void (*callback)(void *param, const struct audio_data *data),
  174. void *param)
  175. {
  176. for (size_t i = 0; i < video->inputs.num; i++) {
  177. struct audio_input *input = video->inputs.array+i;
  178. if (input->callback == callback && input->param == param)
  179. return i;
  180. }
  181. return DARRAY_INVALID;
  182. }
  183. void audio_output_connect(audio_t audio,
  184. struct audio_convert_info *conversion,
  185. void (*callback)(void *param, const struct audio_data *data),
  186. void *param)
  187. {
  188. pthread_mutex_lock(&audio->input_mutex);
  189. if (audio_get_input_idx(audio, callback, param) != DARRAY_INVALID) {
  190. struct audio_input input;
  191. input.callback = callback;
  192. input.param = param;
  193. /* TODO: conversion */
  194. if (conversion) {
  195. input.conversion = *conversion;
  196. } else {
  197. input.conversion.format = audio->info.format;
  198. input.conversion.speakers = audio->info.speakers;
  199. input.conversion.samples_per_sec =
  200. audio->info.samples_per_sec;
  201. }
  202. da_push_back(audio->inputs, &input);
  203. }
  204. pthread_mutex_unlock(&audio->input_mutex);
  205. }
  206. void audio_output_disconnect(audio_t audio,
  207. void (*callback)(void *param, const struct audio_data *data),
  208. void *param)
  209. {
  210. pthread_mutex_lock(&audio->input_mutex);
  211. size_t idx = audio_get_input_idx(audio, callback, param);
  212. if (idx != DARRAY_INVALID)
  213. da_erase(audio->inputs, idx);
  214. pthread_mutex_unlock(&audio->input_mutex);
  215. }
  216. static inline bool valid_audio_params(struct audio_output_info *info)
  217. {
  218. return info->format && info->name && info->samples_per_sec > 0 &&
  219. info->speakers > 0;
  220. }
  221. int audio_output_open(audio_t *audio, struct audio_output_info *info)
  222. {
  223. struct audio_output *out;
  224. pthread_mutexattr_t attr;
  225. if (!valid_audio_params(info))
  226. return AUDIO_OUTPUT_INVALIDPARAM;
  227. out = bmalloc(sizeof(struct audio_output));
  228. memset(out, 0, sizeof(struct audio_output));
  229. memcpy(&out->info, info, sizeof(struct audio_output_info));
  230. pthread_mutex_init_value(&out->line_mutex);
  231. out->channels = get_audio_channels(info->speakers);
  232. out->block_size = out->channels *
  233. get_audio_bytes_per_channel(info->format);
  234. if (pthread_mutexattr_init(&attr) != 0)
  235. goto fail;
  236. if (pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE) != 0)
  237. goto fail;
  238. if (pthread_mutex_init(&out->line_mutex, &attr) != 0)
  239. goto fail;
  240. if (pthread_mutex_init(&out->input_mutex, NULL) != 0)
  241. goto fail;
  242. if (event_init(&out->stop_event, EVENT_TYPE_MANUAL) != 0)
  243. goto fail;
  244. if (pthread_create(&out->thread, NULL, audio_thread, out) != 0)
  245. goto fail;
  246. out->initialized = true;
  247. *audio = out;
  248. return AUDIO_OUTPUT_SUCCESS;
  249. fail:
  250. audio_output_close(out);
  251. return AUDIO_OUTPUT_FAIL;
  252. }
  253. void audio_output_close(audio_t audio)
  254. {
  255. void *thread_ret;
  256. struct audio_line *line;
  257. if (!audio)
  258. return;
  259. if (audio->initialized) {
  260. event_signal(&audio->stop_event);
  261. pthread_join(audio->thread, &thread_ret);
  262. }
  263. line = audio->first_line;
  264. while (line) {
  265. struct audio_line *next = line->next;
  266. audio_line_destroy_data(line);
  267. line = next;
  268. }
  269. da_free(audio->mix_buffer);
  270. da_free(audio->pending_bytes);
  271. event_destroy(&audio->stop_event);
  272. pthread_mutex_destroy(&audio->line_mutex);
  273. bfree(audio);
  274. }
  275. audio_line_t audio_output_createline(audio_t audio, const char *name)
  276. {
  277. struct audio_line *line = bmalloc(sizeof(struct audio_line));
  278. memset(line, 0, sizeof(struct audio_line));
  279. line->alive = true;
  280. line->audio = audio;
  281. if (pthread_mutex_init(&line->mutex, NULL) != 0) {
  282. blog(LOG_ERROR, "audio_output_createline: Failed to create "
  283. "mutex");
  284. bfree(line);
  285. return NULL;
  286. }
  287. pthread_mutex_lock(&audio->line_mutex);
  288. if (audio->first_line) {
  289. audio->first_line->prev_next = &line->next;
  290. line->next = audio->first_line;
  291. }
  292. line->prev_next = &audio->first_line;
  293. audio->first_line = line;
  294. pthread_mutex_unlock(&audio->line_mutex);
  295. line->name = bstrdup(name ? name : "(unnamed audio line)");
  296. return line;
  297. }
  298. const struct audio_output_info *audio_output_getinfo(audio_t audio)
  299. {
  300. return &audio->info;
  301. }
  302. void audio_line_destroy(struct audio_line *line)
  303. {
  304. if (line) {
  305. if (!line->buffer.size)
  306. audio_output_removeline(line->audio, line);
  307. else
  308. line->alive = false;
  309. }
  310. }
  311. size_t audio_output_blocksize(audio_t audio)
  312. {
  313. return audio->block_size;
  314. }
  315. static inline void mul_vol_u8bit(struct audio_line *line, float volume,
  316. size_t total_num)
  317. {
  318. uint8_t *vals = line->volume_buffer.array;
  319. int16_t vol = (int16_t)(volume * 127.0f);
  320. for (size_t i = 0; i < total_num; i++) {
  321. int16_t val = (int16_t)(vals[i] ^ 0x80) << 8;
  322. vals[i] = (uint8_t)((val * vol / 127) + 128);
  323. }
  324. }
  325. static inline void mul_vol_16bit(struct audio_line *line, float volume,
  326. size_t total_num)
  327. {
  328. uint16_t *vals = (uint16_t*)line->volume_buffer.array;
  329. int32_t vol = (int32_t)(volume * 32767.0f);
  330. for (size_t i = 0; i < total_num; i++)
  331. vals[i] = (int32_t)((int32_t)vals[i] * vol / 32767);
  332. }
  333. static inline float conv_24bit_to_float(uint8_t *vals)
  334. {
  335. int32_t val = ((int32_t)vals[0]) |
  336. ((int32_t)vals[1] << 8) |
  337. ((int32_t)vals[2] << 16);
  338. if ((val & 0x800000) != 0)
  339. val |= 0xFF000000;
  340. return (float)val / 8388607.0f;
  341. }
  342. static inline void conv_float_to_24bit(float fval, uint8_t *vals)
  343. {
  344. int32_t val = (int32_t)(fval * 8388607.0f);
  345. vals[0] = (val) & 0xFF;
  346. vals[1] = (val >> 8) & 0xFF;
  347. vals[2] = (val >> 16) & 0xFF;
  348. }
  349. static inline void mul_vol_24bit(struct audio_line *line, float volume,
  350. size_t total_num)
  351. {
  352. uint8_t *vals = line->volume_buffer.array;
  353. for (size_t i = 0; i < total_num; i++) {
  354. float val = conv_24bit_to_float(vals) * volume;
  355. conv_float_to_24bit(val, vals);
  356. vals += 3;
  357. }
  358. }
  359. static inline void mul_vol_32bit(struct audio_line *line, float volume,
  360. size_t total_num)
  361. {
  362. int32_t *vals = (int32_t*)line->volume_buffer.array;
  363. for (size_t i = 0; i < total_num; i++) {
  364. float val = (float)vals[i] / 2147483647.0f;
  365. vals[i] = (int32_t)(val * volume / 2147483647.0f);
  366. }
  367. }
  368. static inline void mul_vol_float(struct audio_line *line, float volume,
  369. size_t total_num)
  370. {
  371. float *vals = (float*)line->volume_buffer.array;
  372. for (size_t i = 0; i < total_num; i++)
  373. vals[i] *= volume;
  374. }
  375. static void audio_line_place_data_pos(struct audio_line *line,
  376. const struct audio_data *data, size_t position)
  377. {
  378. size_t total_num = data->frames * line->audio->channels;
  379. size_t total_size = data->frames * line->audio->block_size;
  380. da_copy_array(line->volume_buffer, data->data, total_size);
  381. switch (line->audio->info.format) {
  382. case AUDIO_FORMAT_U8BIT:
  383. mul_vol_u8bit(line, data->volume, total_num);
  384. break;
  385. case AUDIO_FORMAT_16BIT:
  386. mul_vol_16bit(line, data->volume, total_num);
  387. break;
  388. case AUDIO_FORMAT_32BIT:
  389. mul_vol_32bit(line, data->volume, total_num);
  390. break;
  391. case AUDIO_FORMAT_FLOAT:
  392. mul_vol_float(line, data->volume, total_num);
  393. break;
  394. case AUDIO_FORMAT_UNKNOWN:
  395. break;
  396. }
  397. circlebuf_place(&line->buffer, position, line->volume_buffer.array,
  398. total_size);
  399. }
  400. static inline void audio_line_place_data(struct audio_line *line,
  401. const struct audio_data *data)
  402. {
  403. uint64_t time_offset = data->timestamp - line->base_timestamp;
  404. size_t pos = time_to_bytes(line->audio, time_offset);
  405. audio_line_place_data_pos(line, data, pos);
  406. }
  407. void audio_line_output(audio_line_t line, const struct audio_data *data)
  408. {
  409. /* TODO: prevent insertation of data too far away from expected
  410. * audio timing */
  411. pthread_mutex_lock(&line->mutex);
  412. if (!line->buffer.size) {
  413. line->base_timestamp = data->timestamp;
  414. audio_line_place_data_pos(line, data, 0);
  415. } else if (line->base_timestamp <= data->timestamp) {
  416. audio_line_place_data(line, data);
  417. } else {
  418. blog(LOG_DEBUG, "Bad timestamp for audio line '%s', "
  419. "data->timestamp: %llu, "
  420. "line->base_timestamp: %llu. This can "
  421. "sometimes happen when there's a pause in "
  422. "the threads.", line->name, data->timestamp,
  423. line->base_timestamp);
  424. }
  425. pthread_mutex_unlock(&line->mutex);
  426. }