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.

269 lines
9.6KB

  1. /*
  2. Copyright (C) 2008-2011 Romain Moret at 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 "JackNetCelt.h"
  16. #include "JackError.h"
  17. namespace Jack
  18. {
  19. #define KPS 32
  20. #define KPS_DIV 8
  21. NetCeltAudioBuffer::NetCeltAudioBuffer(session_params_t* params, uint32_t nports, char* net_buffer, int kbps)
  22. :NetAudioBuffer(params, nports, net_buffer)
  23. {
  24. fCeltMode = new CELTMode*[fNPorts];
  25. fCeltEncoder = new CELTEncoder*[fNPorts];
  26. fCeltDecoder = new CELTDecoder*[fNPorts];
  27. memset(fCeltMode, 0, fNPorts * sizeof(CELTMode*));
  28. memset(fCeltEncoder, 0, fNPorts * sizeof(CELTEncoder*));
  29. memset(fCeltDecoder, 0, fNPorts * sizeof(CELTDecoder*));
  30. int error = CELT_OK;
  31. for (int i = 0; i < fNPorts; i++) {
  32. fCeltMode[i] = celt_mode_create(params->fSampleRate, params->fPeriodSize, &error);
  33. if (error != CELT_OK) {
  34. jack_log("NetCeltAudioBuffer celt_mode_create err = %d", error);
  35. goto error;
  36. }
  37. #if HAVE_CELT_API_0_11
  38. fCeltEncoder[i] = celt_encoder_create_custom(fCeltMode[i], 1, &error);
  39. if (error != CELT_OK) {
  40. jack_log("NetCeltAudioBuffer celt_encoder_create_custom err = %d", error);
  41. goto error;
  42. }
  43. celt_encoder_ctl(fCeltEncoder[i], CELT_SET_COMPLEXITY(1));
  44. fCeltDecoder[i] = celt_decoder_create_custom(fCeltMode[i], 1, &error);
  45. if (error != CELT_OK) {
  46. jack_log("NetCeltAudioBuffer celt_decoder_create_custom err = %d", error);
  47. goto error;
  48. }
  49. celt_decoder_ctl(fCeltDecoder[i], CELT_SET_COMPLEXITY(1));
  50. #elif HAVE_CELT_API_0_7 || HAVE_CELT_API_0_8
  51. fCeltEncoder[i] = celt_encoder_create(fCeltMode[i], 1, &error);
  52. if (error != CELT_OK) {
  53. jack_log("NetCeltAudioBuffer celt_mode_create err = %d", error);
  54. goto error;
  55. }
  56. celt_encoder_ctl(fCeltEncoder[i], CELT_SET_COMPLEXITY(1));
  57. fCeltDecoder[i] = celt_decoder_create(fCeltMode[i], 1, &error);
  58. if (error != CELT_OK) {
  59. jack_log("NetCeltAudioBuffer celt_decoder_create err = %d", error);
  60. goto error;
  61. }
  62. celt_decoder_ctl(fCeltDecoder[i], CELT_SET_COMPLEXITY(1));
  63. #else
  64. fCeltEncoder[i] = celt_encoder_create(fCeltMode[i]);
  65. if (error != CELT_OK) {
  66. jack_log("NetCeltAudioBuffer celt_encoder_create err = %d", error);
  67. goto error;
  68. }
  69. celt_encoder_ctl(fCeltEncoder[i], CELT_SET_COMPLEXITY(1));
  70. fCeltDecoder[i] = celt_decoder_create(fCeltMode[i]);
  71. if (error != CELT_OK) {
  72. jack_log("NetCeltAudioBuffer celt_decoder_create err = %d", error);
  73. goto error;
  74. }
  75. celt_decoder_ctl(fCeltDecoder[i], CELT_SET_COMPLEXITY(1));
  76. #endif
  77. }
  78. {
  79. fPeriodSize = params->fPeriodSize;
  80. fCompressedSizeByte = (kbps * params->fPeriodSize * 1024) / (params->fSampleRate * 8);
  81. jack_log("NetCeltAudioBuffer fCompressedSizeByte %d", fCompressedSizeByte);
  82. fCompressedBuffer = new unsigned char* [fNPorts];
  83. for (int port_index = 0; port_index < fNPorts; port_index++) {
  84. fCompressedBuffer[port_index] = new unsigned char[fCompressedSizeByte];
  85. memset(fCompressedBuffer[port_index], 0, fCompressedSizeByte * sizeof(char));
  86. }
  87. int res1 = (fNPorts * fCompressedSizeByte) % PACKET_AVAILABLE_SIZE(params);
  88. int res2 = (fNPorts * fCompressedSizeByte) / PACKET_AVAILABLE_SIZE(params);
  89. fNumPackets = (res1) ? (res2 + 1) : res2;
  90. jack_log("NetCeltAudioBuffer res1 = %d res2 = %d", res1, res2);
  91. fSubPeriodBytesSize = fCompressedSizeByte / fNumPackets;
  92. fLastSubPeriodBytesSize = fSubPeriodBytesSize + fCompressedSizeByte % fNumPackets;
  93. jack_log("NetCeltAudioBuffer fNumPackets = %d fSubPeriodBytesSize = %d, fLastSubPeriodBytesSize = %d", fNumPackets, fSubPeriodBytesSize, fLastSubPeriodBytesSize);
  94. fCycleDuration = float(fSubPeriodBytesSize / sizeof(sample_t)) / float(params->fSampleRate);
  95. fCycleBytesSize = params->fMtu * fNumPackets;
  96. fLastSubCycle = -1;
  97. return;
  98. }
  99. error:
  100. FreeCelt();
  101. throw std::bad_alloc();
  102. }
  103. NetCeltAudioBuffer::~NetCeltAudioBuffer()
  104. {
  105. FreeCelt();
  106. for (int port_index = 0; port_index < fNPorts; port_index++) {
  107. delete [] fCompressedBuffer[port_index];
  108. }
  109. delete [] fCompressedBuffer;
  110. }
  111. void NetCeltAudioBuffer::FreeCelt()
  112. {
  113. for (int i = 0; i < fNPorts; i++) {
  114. if (fCeltEncoder[i]) {
  115. celt_encoder_destroy(fCeltEncoder[i]);
  116. }
  117. if (fCeltDecoder[i]) {
  118. celt_decoder_destroy(fCeltDecoder[i]);
  119. }
  120. if (fCeltMode[i]) {
  121. celt_mode_destroy(fCeltMode[i]);
  122. }
  123. }
  124. delete [] fCeltMode;
  125. delete [] fCeltEncoder;
  126. delete [] fCeltDecoder;
  127. }
  128. size_t NetCeltAudioBuffer::GetCycleSize()
  129. {
  130. return fCycleBytesSize;
  131. }
  132. float NetCeltAudioBuffer::GetCycleDuration()
  133. {
  134. return fCycleDuration;
  135. }
  136. int NetCeltAudioBuffer::GetNumPackets(int active_ports)
  137. {
  138. return fNumPackets;
  139. }
  140. int NetCeltAudioBuffer::RenderFromJackPorts(int nframes)
  141. {
  142. float buffer[BUFFER_SIZE_MAX];
  143. for (int port_index = 0; port_index < fNPorts; port_index++) {
  144. if (fPortBuffer[port_index]) {
  145. memcpy(buffer, fPortBuffer[port_index], fPeriodSize * sizeof(sample_t));
  146. } else {
  147. memset(buffer, 0, fPeriodSize * sizeof(sample_t));
  148. }
  149. #if HAVE_CELT_API_0_8 || HAVE_CELT_API_0_11
  150. //int res = celt_encode_float(fCeltEncoder[port_index], buffer, fPeriodSize, fCompressedBuffer[port_index], fCompressedSizeByte);
  151. int res = celt_encode_float(fCeltEncoder[port_index], buffer, nframes, fCompressedBuffer[port_index], fCompressedSizeByte);
  152. #else
  153. int res = celt_encode_float(fCeltEncoder[port_index], buffer, NULL, fCompressedBuffer[port_index], fCompressedSizeByte);
  154. #endif
  155. if (res != fCompressedSizeByte) {
  156. jack_error("celt_encode_float error fCompressedSizeByte = %d res = %d", fCompressedSizeByte, res);
  157. }
  158. }
  159. // All ports active
  160. return fNPorts;
  161. }
  162. void NetCeltAudioBuffer::RenderToJackPorts(int nframes)
  163. {
  164. for (int port_index = 0; port_index < fNPorts; port_index++) {
  165. if (fPortBuffer[port_index]) {
  166. #if HAVE_CELT_API_0_8 || HAVE_CELT_API_0_11
  167. //int res = celt_decode_float(fCeltDecoder[port_index], fCompressedBuffer[port_index], fCompressedSizeByte, fPortBuffer[port_index], fPeriodSize);
  168. int res = celt_decode_float(fCeltDecoder[port_index], fCompressedBuffer[port_index], fCompressedSizeByte, fPortBuffer[port_index], nframes);
  169. #else
  170. int res = celt_decode_float(fCeltDecoder[port_index], fCompressedBuffer[port_index], fCompressedSizeByte, fPortBuffer[port_index]);
  171. #endif
  172. if (res != CELT_OK) {
  173. jack_error("celt_decode_float error fCompressedSizeByte = %d res = %d", fCompressedSizeByte, res);
  174. }
  175. }
  176. }
  177. NextCycle();
  178. }
  179. //network<->buffer
  180. int NetCeltAudioBuffer::RenderFromNetwork(int cycle, int sub_cycle, uint32_t port_num)
  181. {
  182. // Cleanup all JACK ports at the beginning of the cycle
  183. if (sub_cycle == 0) {
  184. Cleanup();
  185. }
  186. if (port_num > 0) {
  187. int sub_period_bytes_size;
  188. // Last packet of the cycle
  189. if (sub_cycle == fNumPackets - 1) {
  190. sub_period_bytes_size = fLastSubPeriodBytesSize;
  191. } else {
  192. sub_period_bytes_size = fSubPeriodBytesSize;
  193. }
  194. for (int port_index = 0; port_index < fNPorts; port_index++) {
  195. memcpy(fCompressedBuffer[port_index] + sub_cycle * fSubPeriodBytesSize, fNetBuffer + port_index * sub_period_bytes_size, sub_period_bytes_size);
  196. }
  197. }
  198. return CheckPacket(cycle, sub_cycle);
  199. }
  200. int NetCeltAudioBuffer::RenderToNetwork(int sub_cycle, uint32_t port_num)
  201. {
  202. int sub_period_bytes_size;
  203. // Last packet of the cycle
  204. if (sub_cycle == fNumPackets - 1) {
  205. sub_period_bytes_size = fLastSubPeriodBytesSize;
  206. } else {
  207. sub_period_bytes_size = fSubPeriodBytesSize;
  208. }
  209. for (int port_index = 0; port_index < fNPorts; port_index++) {
  210. memcpy(fNetBuffer + port_index * sub_period_bytes_size, fCompressedBuffer[port_index] + sub_cycle * fSubPeriodBytesSize, sub_period_bytes_size);
  211. }
  212. return fNPorts * sub_period_bytes_size;
  213. }
  214. }