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.

204 lines
5.8KB

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