audio-io.c 3.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131
  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 3 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/platform.h"
  17. #include "audio-io.h"
  18. /* TODO: Incomplete */
  19. struct audio_output {
  20. struct audio_info info;
  21. media_t media;
  22. media_output_t output;
  23. pthread_t thread;
  24. pthread_mutex_t data_mutex;
  25. event_t stop_event;
  26. struct darray pending_frames;
  27. bool initialized;
  28. };
  29. /* ------------------------------------------------------------------------- */
  30. static void *audio_thread(void *param)
  31. {
  32. struct audio_output *audio = param;
  33. while (event_try(&audio->stop_event) == EAGAIN) {
  34. os_sleep_ms(5);
  35. /* TODO */
  36. }
  37. return NULL;
  38. }
  39. /* ------------------------------------------------------------------------- */
  40. static inline bool valid_audio_params(struct audio_info *info)
  41. {
  42. return info->channels > 0 && info->format && info->name &&
  43. info->samples_per_sec > 0 && info->speakers > 0;
  44. }
  45. static inline bool ao_add_to_media(audio_t audio)
  46. {
  47. struct media_output_info oi;
  48. oi.format = audio->info.format;
  49. oi.obj = audio;
  50. oi.connect = NULL;
  51. audio->output = media_output_create(&oi);
  52. if (!audio->output)
  53. return false;
  54. media_add_output(audio->media, audio->output);
  55. return true;
  56. }
  57. int audio_output_open(audio_t *audio, media_t media, struct audio_info *info)
  58. {
  59. struct audio_output *out;
  60. if (!valid_audio_params(info))
  61. return AUDIO_OUTPUT_INVALIDPARAM;
  62. out = bmalloc(sizeof(struct audio_output));
  63. memset(out, 0, sizeof(struct audio_output));
  64. memcpy(&out->info, info, sizeof(struct audio_info));
  65. out->media = media;
  66. if (pthread_mutex_init(&out->data_mutex, NULL) != 0)
  67. goto fail;
  68. if (event_init(&out->stop_event, true) != 0)
  69. goto fail;
  70. if (!ao_add_to_media(out))
  71. goto fail;
  72. if (pthread_create(&out->thread, NULL, audio_thread, out) != 0)
  73. goto fail;
  74. out->initialized = true;
  75. *audio = out;
  76. return AUDIO_OUTPUT_SUCCESS;
  77. fail:
  78. audio_output_close(out);
  79. return AUDIO_OUTPUT_FAIL;
  80. }
  81. void audio_output_data(audio_t audio, struct audio_data *data)
  82. {
  83. pthread_mutex_lock(&audio->data_mutex);
  84. /* TODO */
  85. pthread_mutex_unlock(&audio->data_mutex);
  86. }
  87. void audio_output_close(audio_t audio)
  88. {
  89. void *thread_ret;
  90. if (!audio)
  91. return;
  92. if (audio->initialized) {
  93. event_signal(&audio->stop_event);
  94. pthread_join(audio->thread, &thread_ret);
  95. }
  96. media_remove_output(audio->media, audio->output);
  97. event_destroy(&audio->stop_event);
  98. pthread_mutex_destroy(&audio->data_mutex);
  99. bfree(audio);
  100. }