Audio plugin host https://kx.studio/carla
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

143 lines
3.3KB

  1. /*
  2. * Wine+JACK Test
  3. * Copyright (C) 2015 Filipe Coelho <falktx@falktx.com>
  4. *
  5. * This program is free software; you can redistribute it and/or
  6. * modify it under the terms of the GNU General Public License as
  7. * published by the Free Software Foundation; either version 2 of
  8. * the License, or any later version.
  9. *
  10. * This program is distributed in the hope that it will be useful,
  11. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  12. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  13. * GNU General Public License for more details.
  14. *
  15. * For a full copy of the GNU General Public License see the doc/GPL.txt file.
  16. */
  17. #include <semaphore.h>
  18. #include <stdio.h>
  19. #include <signal.h>
  20. #include <unistd.h>
  21. #include <windows.h>
  22. #include <sys/types.h>
  23. #include <jack/jack.h>
  24. #undef _WIN32
  25. #include <jack/thread.h>
  26. static bool gCloseNow = false;
  27. static void _close(int)
  28. {
  29. gCloseNow = true;
  30. }
  31. static int _process(jack_nframes_t, void*)
  32. {
  33. printf("%s\n", __PRETTY_FUNCTION__);
  34. return 0;
  35. }
  36. #if 0
  37. // TEST
  38. void* (*creator_func)(void*) = NULL;
  39. void* creator_arg = NULL;
  40. HANDLE creator_handle = 0;
  41. pthread_t creator_pthread = 0;
  42. static DWORD WINAPI thread_creator_helper(LPVOID)
  43. {
  44. printf("%s\n", __PRETTY_FUNCTION__);
  45. creator_pthread = pthread_self();
  46. SetEvent(creator_handle);
  47. creator_func(creator_arg);
  48. return 0;
  49. }
  50. static int thread_creator(pthread_t* thread_id, const pthread_attr_t*, void *(*function)(void*), void* arg)
  51. {
  52. printf("%s\n", __PRETTY_FUNCTION__);
  53. creator_func = function;
  54. creator_arg = arg;
  55. creator_handle = ::CreateEventA(NULL, false, false, NULL);
  56. ::CreateThread(NULL, 0, thread_creator_helper, arg, 0, 0);
  57. ::WaitForSingleObject(creator_handle, INFINITE);
  58. *thread_id = creator_pthread;
  59. return 0;
  60. }
  61. #endif
  62. struct JackWineThread {
  63. void* (*func)(void*);
  64. void* arg;
  65. pthread_t pthid;
  66. sem_t sema;
  67. };
  68. static DWORD WINAPI
  69. wine_thread_aux( LPVOID arg ) {
  70. struct JackWineThread* jwt = (struct JackWineThread*) arg;
  71. printf("%s\n", __PRETTY_FUNCTION__);
  72. void* func_arg = jwt->arg;
  73. void* (*func)(void*) = jwt->func;
  74. jwt->pthid = pthread_self();
  75. sem_post( &jwt->sema );
  76. func ( func_arg );
  77. return 0;
  78. }
  79. static int
  80. wine_thread_create (pthread_t* thread_id, const pthread_attr_t*, void *(*function)(void*), void* arg) {
  81. struct JackWineThread jwt;
  82. printf("%s\n", __PRETTY_FUNCTION__);
  83. sem_init( &jwt.sema, 0, 0 );
  84. jwt.func = function;
  85. jwt.arg = arg;
  86. CreateThread( NULL, 0, wine_thread_aux, &jwt, 0, 0 );
  87. sem_wait( &jwt.sema );
  88. *thread_id = jwt.pthid;
  89. return 0;
  90. }
  91. int main()
  92. {
  93. struct sigaction sterm;
  94. sterm.sa_handler = _close;
  95. sterm.sa_flags = SA_RESTART;
  96. sterm.sa_restorer = NULL;
  97. sigemptyset(&sterm.sa_mask);
  98. sigaction(SIGTERM, &sterm, NULL);
  99. sigaction(SIGINT, &sterm, NULL);
  100. jack_set_thread_creator(wine_thread_create);
  101. jack_client_t* const client = jack_client_open("WineJack2", JackNullOption, NULL);
  102. if (client == NULL)
  103. return 1;
  104. jack_set_process_callback(client, _process, NULL);
  105. jack_activate(client);
  106. for (; ! gCloseNow;) {
  107. usleep(100000);
  108. }
  109. jack_deactivate(client);
  110. jack_client_close(client);
  111. return 0;
  112. }