jack2 codebase
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.

159 lines
6.4KB

  1. /*
  2. Copyright (C) 2014 Samsung Electronics
  3. This program is free software; you can redistribute it and/or modify
  4. it under the terms of the GNU Lesser General Public License as published by
  5. the Free Software Foundation; either version 2.1 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 Lesser General Public License for more details.
  11. You should have received a copy of the GNU Lesser General Public License
  12. along with this program; if not, write to the Free Software
  13. Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
  14. */
  15. #include "JackSapaProxy.h"
  16. #include "JackServerGlobals.h"
  17. #include "JackEngineControl.h"
  18. #include "JackLockedEngine.h"
  19. #include "JackArgParser.h"
  20. #include <assert.h>
  21. #include <string>
  22. // Example)
  23. // sapaproxy
  24. // .----------.
  25. // sapaproxy:__system_capture_1 -->| |--> sapaproxy:capture_1
  26. // sapaproxy:__system_capture_2 -->| |--> sapaproxy:capture_2
  27. // ... | | ...
  28. // | |
  29. // sapaproxy:playback_1 ---------->| |--> sapaproxy:__system_playback_1
  30. // sapaproxy:playback_2 ---------->| |--> sapaproxy:__system_playback_2
  31. // sapaproxy:playback_3 ---------->| |--> sapaproxy:__system_playback_3
  32. // sapaproxy:playback_4 ---------->| |--> sapaproxy:__system_playback_4
  33. // ... | | ...
  34. // '----------'
  35. namespace Jack
  36. {
  37. JackSapaProxy::JackSapaProxy(jack_client_t* client, const JSList* params)
  38. :fClient(client)
  39. {
  40. jack_log("JackSapaProxy::JackSapaProxy");
  41. fCapturePorts = fPlaybackPorts = 0;
  42. const JSList* node;
  43. const jack_driver_param_t* param;
  44. for (node = params; node; node = jack_slist_next(node)) {
  45. param = (const jack_driver_param_t*)node->data;
  46. switch (param->character) {
  47. case 'C':
  48. fCapturePorts = (param->value.ui > SAPAPROXY_PORT_NUM_FOR_CLIENT)? SAPAPROXY_PORT_NUM_FOR_CLIENT : param->value.ui;
  49. break;
  50. case 'P':
  51. fPlaybackPorts = (param->value.ui > SAPAPROXY_PORT_NUM_FOR_CLIENT)? SAPAPROXY_PORT_NUM_FOR_CLIENT : param->value.ui;
  52. break;
  53. }
  54. }
  55. }
  56. JackSapaProxy::~JackSapaProxy()
  57. {
  58. jack_log("JackSapaProxy::~JackSapaProxy");
  59. }
  60. int JackSapaProxy::Setup(jack_client_t* client)
  61. {
  62. jack_log("JackSapaProxy::Setup");
  63. //refer to system ports and create sapaproxy ports
  64. unsigned int i = 0, j = 0;
  65. const char **ports_system_capture;
  66. const char **ports_system_playback;
  67. unsigned int ports_system_capture_cnt = 0;
  68. unsigned int ports_system_playback_cnt = 0;
  69. char port_name[JACK_PORT_NAME_SIZE] = {0,};
  70. ports_system_capture = jack_get_ports(client, "system:.*", NULL, JackPortIsPhysical | JackPortIsOutput);
  71. if (ports_system_capture != NULL) {
  72. for (i = 0; i < fCapturePorts && ports_system_capture[i]; i++) {
  73. sprintf(port_name, "__system_capture_%d", i + 1);
  74. fInputPorts[i] = jack_port_register(client, port_name, JACK_DEFAULT_AUDIO_TYPE, JackPortIsInput, 0);
  75. sprintf(port_name, "capture_%d", i + 1);
  76. fOutputPorts[i] = jack_port_register(client, port_name, JACK_DEFAULT_AUDIO_TYPE, JackPortIsOutput, 0);
  77. ports_system_capture_cnt++;
  78. }
  79. jack_free(ports_system_capture);
  80. }
  81. ports_system_playback = jack_get_ports(client, "system:.*", NULL, JackPortIsPhysical | JackPortIsInput);
  82. if (ports_system_playback != NULL) {
  83. for (j = 0; j < fPlaybackPorts && ports_system_playback[j]; j++, i++) {
  84. sprintf(port_name, "playback_%d", j + 1);
  85. fInputPorts[i] = jack_port_register(client, port_name, JACK_DEFAULT_AUDIO_TYPE, JackPortIsInput, 0);
  86. sprintf(port_name, "__system_playback_%d", j + 1);
  87. fOutputPorts[i] = jack_port_register(client, port_name, JACK_DEFAULT_AUDIO_TYPE, JackPortIsOutput, 0);
  88. ports_system_playback_cnt++;
  89. }
  90. jack_free(ports_system_playback);
  91. }
  92. //store actual number of system ports
  93. fCapturePorts = ports_system_capture_cnt;
  94. fPlaybackPorts = ports_system_playback_cnt;
  95. jack_set_process_callback(client, Process, this);
  96. jack_activate(client);
  97. //connect between sapaproxy and system ports
  98. for (unsigned int i = 0; i < ports_system_capture_cnt; i++) {
  99. sprintf(port_name, "system:capture_%d", i + 1);
  100. jack_connect(client, port_name, jack_port_name(fInputPorts[i]));
  101. }
  102. for (unsigned int i = 0; i < ports_system_playback_cnt; i++) {
  103. sprintf(port_name, "system:playback_%d", i + 1);
  104. jack_connect(client, jack_port_name(fOutputPorts[ports_system_capture_cnt + i]), port_name);
  105. }
  106. return 0;
  107. }
  108. int JackSapaProxy::Process(jack_nframes_t nframes, void* arg)
  109. {
  110. JackSapaProxy* sapaproxy = static_cast<JackSapaProxy*>(arg);
  111. jack_default_audio_sample_t *in, *out;
  112. //for capture
  113. for (unsigned int i = 0; i < sapaproxy->fCapturePorts; i++) {
  114. in = (jack_default_audio_sample_t*)jack_port_get_buffer(sapaproxy->fInputPorts[i] , nframes);
  115. out = (jack_default_audio_sample_t*)jack_port_get_buffer(sapaproxy->fOutputPorts[i], nframes);
  116. // TODO: adjust pcm gain each platform here
  117. memcpy(out, in, sizeof(jack_default_audio_sample_t) * nframes);
  118. }
  119. //for playback
  120. for (unsigned int i = sapaproxy->fCapturePorts; i < (sapaproxy->fCapturePorts + sapaproxy->fPlaybackPorts); i++) {
  121. in = (jack_default_audio_sample_t*)jack_port_get_buffer(sapaproxy->fInputPorts[i] , nframes);
  122. out = (jack_default_audio_sample_t*)jack_port_get_buffer(sapaproxy->fOutputPorts[i], nframes);
  123. // TODO: adjust pcm gain each platform here
  124. memcpy(out, in, sizeof(jack_default_audio_sample_t) * nframes);
  125. }
  126. return 0;
  127. }
  128. } // namespace Jack