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.

207 lines
5.9KB

  1. /*
  2. Copyright (C) 2008 Grame
  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, write to the Free Software
  13. Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  14. */
  15. #include "JackNetIOAdapter.h"
  16. #include "JackError.h"
  17. #include "JackExports.h"
  18. #include <stdio.h>
  19. #include <assert.h>
  20. using namespace std;
  21. namespace Jack
  22. {
  23. #define DEFAULT_RB_SIZE 16384
  24. int JackNetIOAdapter::Process(jack_nframes_t frames, void* arg)
  25. {
  26. JackNetIOAdapter* adapter = static_cast<JackNetIOAdapter*>(arg);
  27. char* buffer;
  28. int i;
  29. if (!adapter->fIOAdapter->IsRunning())
  30. return 0;
  31. for (i = 0; i < adapter->fCaptureChannels; i++) {
  32. buffer = static_cast<char*>(jack_port_get_buffer(adapter->fCapturePortList[i], frames));
  33. size_t len = jack_ringbuffer_read_space(adapter->fCaptureRingBuffer);
  34. if (len < frames * sizeof(float)) {
  35. jack_error("JackNetIOAdapter::Process : consumer too slow, skip frames = %d", (frames * sizeof(float)) - len);
  36. jack_ringbuffer_read(adapter->fCaptureRingBuffer, buffer, len);
  37. } else {
  38. jack_ringbuffer_read(adapter->fCaptureRingBuffer, buffer, frames * sizeof(float));
  39. }
  40. }
  41. for (i = 0; i < adapter->fPlaybackChannels; i++) {
  42. buffer = static_cast<char*>(jack_port_get_buffer(adapter->fPlaybackPortList[i], frames));
  43. size_t len = jack_ringbuffer_write_space(adapter->fPlaybackRingBuffer);
  44. if (len < frames * sizeof(float)) {
  45. jack_error("JackNetIOAdapter::Process : producer too slow, missing frames = %d", (frames * sizeof(float)) - len);
  46. jack_ringbuffer_write(adapter->fPlaybackRingBuffer, buffer, len);
  47. } else {
  48. jack_ringbuffer_write(adapter->fPlaybackRingBuffer, buffer, frames * sizeof(float));
  49. }
  50. }
  51. return 0;
  52. }
  53. JackNetIOAdapter::JackNetIOAdapter(jack_client_t* jack_client,
  54. JackIOAdapterInterface* audio_io,
  55. int input,
  56. int output)
  57. {
  58. int i;
  59. char name[32];
  60. fJackClient = jack_client;
  61. fCaptureChannels = input;
  62. fPlaybackChannels = output;
  63. fIOAdapter = audio_io;
  64. fCapturePortList = new jack_port_t* [fCaptureChannels];
  65. fPlaybackPortList = new jack_port_t* [fPlaybackChannels];
  66. fCaptureRingBuffer = jack_ringbuffer_create(fCaptureChannels * sizeof(float) * DEFAULT_RB_SIZE);
  67. if (fCaptureRingBuffer == NULL)
  68. goto fail;
  69. fPlaybackRingBuffer = jack_ringbuffer_create(fPlaybackChannels * sizeof(float) * DEFAULT_RB_SIZE);
  70. if (fPlaybackRingBuffer == NULL)
  71. goto fail;
  72. fIOAdapter->SetRingBuffers(fCaptureRingBuffer, fPlaybackRingBuffer);
  73. for (i = 0; i < fCaptureChannels; i++) {
  74. sprintf(name, "capture_%d", i+1);
  75. if ((fCapturePortList[i] = jack_port_register(fJackClient, name, JACK_DEFAULT_AUDIO_TYPE, JackPortIsOutput, 0)) == NULL)
  76. goto fail;
  77. }
  78. for (i = 0; i < fPlaybackChannels; i++) {
  79. sprintf(name, "playback_%d", i+1);
  80. if ((fPlaybackPortList[i] = jack_port_register(fJackClient, name, JACK_DEFAULT_AUDIO_TYPE, JackPortIsInput, 0)) == NULL)
  81. goto fail;
  82. }
  83. if (jack_set_process_callback(fJackClient, Process, this) < 0)
  84. goto fail;
  85. if (jack_activate(fJackClient) < 0)
  86. goto fail;
  87. return;
  88. fail:
  89. FreePorts();
  90. }
  91. JackNetIOAdapter::~JackNetIOAdapter()
  92. {
  93. // When called Close has already been sued for the client, thus ports are already unregistered.
  94. delete fIOAdapter;
  95. }
  96. void JackNetIOAdapter::FreePorts()
  97. {
  98. int i;
  99. if (fCaptureRingBuffer)
  100. jack_ringbuffer_free(fCaptureRingBuffer);
  101. if (fPlaybackRingBuffer)
  102. jack_ringbuffer_free(fPlaybackRingBuffer);
  103. for (i = 0; i < fCaptureChannels; i++) {
  104. if (fCapturePortList[i])
  105. jack_port_unregister(fJackClient, fCapturePortList[i]);
  106. }
  107. for (i = 0; i < fCaptureChannels; i++) {
  108. if (fPlaybackPortList[i])
  109. jack_port_unregister(fJackClient, fPlaybackPortList[i]);
  110. }
  111. delete[] fCapturePortList;
  112. delete[] fPlaybackPortList;
  113. }
  114. int JackNetIOAdapter::Open()
  115. {
  116. return fIOAdapter->Open();
  117. }
  118. int JackNetIOAdapter::Close()
  119. {
  120. return fIOAdapter->Close();
  121. }
  122. } //namespace
  123. static Jack::JackNetIOAdapter* adapter = NULL;
  124. #ifdef __cplusplus
  125. extern "C"
  126. {
  127. #endif
  128. #include "JackCoreAudioIOAdapter.h"
  129. #include "JackPortAudioIOAdapter.h"
  130. EXPORT int jack_initialize(jack_client_t* jack_client, const char* load_init)
  131. {
  132. if (adapter) {
  133. jack_error("NetAudio Adapter already loaded");
  134. return 1;
  135. } else {
  136. jack_log("Loading NetAudio Adapter");
  137. // adapter = new Jack::JackNetIOAdapter(jack_client, new Jack::JackCoreAudioIOAdapter(2, 2, 512, 44100.f), 2, 2);
  138. adapter = new Jack::JackNetIOAdapter(jack_client,
  139. new Jack::JackPortAudioIOAdapter(2, 2, jack_get_buffer_size(jack_client), jack_get_sample_rate(jack_client)), 2, 2);
  140. assert(adapter);
  141. if (adapter->Open() == 0) {
  142. return 0;
  143. } else {
  144. delete adapter;
  145. adapter = NULL;
  146. return 1;
  147. }
  148. }
  149. }
  150. EXPORT void jack_finish(void* arg)
  151. {
  152. if (adapter) {
  153. jack_log("Unloading NetAudio Adapter");
  154. adapter->Close();
  155. delete adapter;
  156. adapter = NULL;
  157. }
  158. }
  159. #ifdef __cplusplus
  160. }
  161. #endif