test-sinewave.c 2.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110
  1. #include <math.h>
  2. #include <util/bmem.h>
  3. #include <util/threading.h>
  4. #include <util/platform.h>
  5. #include <obs.h>
  6. struct sinewave_data {
  7. bool initialized_thread;
  8. pthread_t thread;
  9. os_event_t *event;
  10. obs_source_t *source;
  11. };
  12. /* middle C */
  13. static const double rate = 261.63 / 48000.0;
  14. #ifndef M_PI
  15. #define M_PI 3.1415926535897932384626433832795
  16. #endif
  17. #define M_PI_X2 M_PI * 2
  18. static void *sinewave_thread(void *pdata)
  19. {
  20. struct sinewave_data *swd = pdata;
  21. uint64_t last_time = os_gettime_ns();
  22. uint64_t ts = 0;
  23. double cos_val = 0.0;
  24. uint8_t bytes[480];
  25. while (os_event_try(swd->event) == EAGAIN) {
  26. if (!os_sleepto_ns(last_time += 10000000))
  27. last_time = os_gettime_ns();
  28. for (size_t i = 0; i < 480; i++) {
  29. cos_val += rate * M_PI_X2;
  30. if (cos_val > M_PI_X2)
  31. cos_val -= M_PI_X2;
  32. double wave = cos(cos_val) * 0.5;
  33. bytes[i] = (uint8_t)((wave + 1.0) * 0.5 * 255.0);
  34. }
  35. struct obs_source_audio data;
  36. data.data[0] = bytes;
  37. data.frames = 480;
  38. data.speakers = SPEAKERS_MONO;
  39. data.samples_per_sec = 48000;
  40. data.timestamp = ts;
  41. data.format = AUDIO_FORMAT_U8BIT;
  42. obs_source_output_audio(swd->source, &data);
  43. ts += 10000000;
  44. }
  45. return NULL;
  46. }
  47. /* ------------------------------------------------------------------------- */
  48. static const char *sinewave_getname(void *unused)
  49. {
  50. UNUSED_PARAMETER(unused);
  51. return "Sinewave Sound Source (Test)";
  52. }
  53. static void sinewave_destroy(void *data)
  54. {
  55. struct sinewave_data *swd = data;
  56. if (swd) {
  57. if (swd->initialized_thread) {
  58. void *ret;
  59. os_event_signal(swd->event);
  60. pthread_join(swd->thread, &ret);
  61. }
  62. os_event_destroy(swd->event);
  63. bfree(swd);
  64. }
  65. }
  66. static void *sinewave_create(obs_data_t *settings, obs_source_t *source)
  67. {
  68. struct sinewave_data *swd = bzalloc(sizeof(struct sinewave_data));
  69. swd->source = source;
  70. if (os_event_init(&swd->event, OS_EVENT_TYPE_MANUAL) != 0)
  71. goto fail;
  72. if (pthread_create(&swd->thread, NULL, sinewave_thread, swd) != 0)
  73. goto fail;
  74. swd->initialized_thread = true;
  75. UNUSED_PARAMETER(settings);
  76. return swd;
  77. fail:
  78. sinewave_destroy(swd);
  79. return NULL;
  80. }
  81. struct obs_source_info test_sinewave = {
  82. .id = "test_sinewave",
  83. .type = OBS_SOURCE_TYPE_INPUT,
  84. .output_flags = OBS_SOURCE_AUDIO,
  85. .get_name = sinewave_getname,
  86. .create = sinewave_create,
  87. .destroy = sinewave_destroy,
  88. };