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.

244 lines
9.8KB

  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 "JackNetOpus.h"
  16. #include "JackError.h"
  17. namespace Jack
  18. {
  19. #define CDO (sizeof(short)) ///< compressed data offset (first 2 bytes are length)
  20. NetOpusAudioBuffer::NetOpusAudioBuffer(session_params_t* params, uint32_t nports, char* net_buffer, int kbps)
  21. :NetAudioBuffer(params, nports, net_buffer)
  22. {
  23. fOpusMode = new OpusCustomMode*[fNPorts];
  24. fOpusEncoder = new OpusCustomEncoder*[fNPorts];
  25. fOpusDecoder = new OpusCustomDecoder*[fNPorts];
  26. fCompressedSizesByte = new unsigned short[fNPorts];
  27. memset(fOpusMode, 0, fNPorts * sizeof(OpusCustomMode*));
  28. memset(fOpusEncoder, 0, fNPorts * sizeof(OpusCustomEncoder*));
  29. memset(fOpusDecoder, 0, fNPorts * sizeof(OpusCustomDecoder*));
  30. memset(fCompressedSizesByte, 0, fNPorts * sizeof(short));
  31. int error = OPUS_OK;
  32. for (int i = 0; i < fNPorts; i++) {
  33. /* Allocate en/decoders */
  34. fOpusMode[i] = opus_custom_mode_create(params->fSampleRate, params->fPeriodSize, &error);
  35. if (error != OPUS_OK) {
  36. jack_log("NetOpusAudioBuffer opus_custom_mode_create err = %d", error);
  37. goto error;
  38. }
  39. fOpusEncoder[i] = opus_custom_encoder_create(fOpusMode[i], 1, &error);
  40. if (error != OPUS_OK) {
  41. jack_log("NetOpusAudioBuffer opus_custom_encoder_create err = %d", error);
  42. goto error;
  43. }
  44. fOpusDecoder[i] = opus_custom_decoder_create(fOpusMode[i], 1, &error);
  45. if (error != OPUS_OK) {
  46. jack_log("NetOpusAudioBuffer opus_custom_decoder_create err = %d", error);
  47. goto error;
  48. }
  49. opus_custom_encoder_ctl(fOpusEncoder[i], OPUS_SET_BITRATE(kbps*1024)); // bits per second
  50. opus_custom_encoder_ctl(fOpusEncoder[i], OPUS_SET_COMPLEXITY(10));
  51. opus_custom_encoder_ctl(fOpusEncoder[i], OPUS_SET_SIGNAL(OPUS_SIGNAL_MUSIC));
  52. opus_custom_encoder_ctl(fOpusEncoder[i], OPUS_SET_SIGNAL(OPUS_APPLICATION_RESTRICTED_LOWDELAY));
  53. }
  54. {
  55. fCompressedMaxSizeByte = (kbps * params->fPeriodSize * 1024) / (params->fSampleRate * 8);
  56. fPeriodSize = params->fPeriodSize;
  57. jack_log("NetOpusAudioBuffer fCompressedMaxSizeByte %d", fCompressedMaxSizeByte);
  58. fCompressedBuffer = new unsigned char* [fNPorts];
  59. for (int port_index = 0; port_index < fNPorts; port_index++) {
  60. fCompressedBuffer[port_index] = new unsigned char[fCompressedMaxSizeByte];
  61. memset(fCompressedBuffer[port_index], 0, fCompressedMaxSizeByte * sizeof(char));
  62. }
  63. int res1 = (fNPorts * fCompressedMaxSizeByte + CDO) % PACKET_AVAILABLE_SIZE(params);
  64. int res2 = (fNPorts * fCompressedMaxSizeByte + CDO) / PACKET_AVAILABLE_SIZE(params);
  65. fNumPackets = (res1) ? (res2 + 1) : res2;
  66. jack_log("NetOpusAudioBuffer res1 = %d res2 = %d", res1, res2);
  67. fSubPeriodBytesSize = (fCompressedMaxSizeByte + CDO) / fNumPackets;
  68. fLastSubPeriodBytesSize = fSubPeriodBytesSize + (fCompressedMaxSizeByte + CDO) % fNumPackets;
  69. if (fNumPackets == 1) {
  70. fSubPeriodBytesSize = fLastSubPeriodBytesSize;
  71. }
  72. jack_log("NetOpusAudioBuffer fNumPackets = %d fSubPeriodBytesSize = %d, fLastSubPeriodBytesSize = %d", fNumPackets, fSubPeriodBytesSize, fLastSubPeriodBytesSize);
  73. fCycleDuration = float(fSubPeriodBytesSize / sizeof(sample_t)) / float(params->fSampleRate);
  74. fCycleBytesSize = params->fMtu * fNumPackets;
  75. fLastSubCycle = -1;
  76. return;
  77. }
  78. error:
  79. FreeOpus();
  80. throw std::bad_alloc();
  81. }
  82. NetOpusAudioBuffer::~NetOpusAudioBuffer()
  83. {
  84. FreeOpus();
  85. for (int port_index = 0; port_index < fNPorts; port_index++) {
  86. delete [] fCompressedBuffer[port_index];
  87. }
  88. delete [] fCompressedBuffer;
  89. delete [] fCompressedSizesByte;
  90. }
  91. void NetOpusAudioBuffer::FreeOpus()
  92. {
  93. for (int i = 0; i < fNPorts; i++) {
  94. if (fOpusEncoder[i]) {
  95. opus_custom_encoder_destroy(fOpusEncoder[i]);
  96. fOpusEncoder[i] = 0;
  97. }
  98. if (fOpusDecoder[i]) {
  99. opus_custom_decoder_destroy(fOpusDecoder[i]);
  100. fOpusDecoder[i] = 0;
  101. }
  102. if (fOpusMode[i]) {
  103. opus_custom_mode_destroy(fOpusMode[i]);
  104. fOpusMode[i] = 0;
  105. }
  106. }
  107. delete [] fOpusEncoder;
  108. delete [] fOpusDecoder;
  109. delete [] fOpusMode;
  110. }
  111. size_t NetOpusAudioBuffer::GetCycleSize()
  112. {
  113. return fCycleBytesSize;
  114. }
  115. float NetOpusAudioBuffer::GetCycleDuration()
  116. {
  117. return fCycleDuration;
  118. }
  119. int NetOpusAudioBuffer::GetNumPackets(int active_ports)
  120. {
  121. return fNumPackets;
  122. }
  123. int NetOpusAudioBuffer::RenderFromJackPorts(int nframes)
  124. {
  125. float buffer[BUFFER_SIZE_MAX];
  126. for (int port_index = 0; port_index < fNPorts; port_index++) {
  127. if (fPortBuffer[port_index]) {
  128. memcpy(buffer, fPortBuffer[port_index], fPeriodSize * sizeof(sample_t));
  129. } else {
  130. memset(buffer, 0, fPeriodSize * sizeof(sample_t));
  131. }
  132. int res = opus_custom_encode_float(fOpusEncoder[port_index], buffer, ((nframes == -1) ? fPeriodSize : nframes), fCompressedBuffer[port_index], fCompressedMaxSizeByte);
  133. if (res < 0 || res >= 65535) {
  134. jack_error("opus_custom_encode_float error res = %d", res);
  135. fCompressedSizesByte[port_index] = 0;
  136. } else {
  137. fCompressedSizesByte[port_index] = res;
  138. }
  139. }
  140. // All ports active
  141. return fNPorts;
  142. }
  143. void NetOpusAudioBuffer::RenderToJackPorts(int nframes)
  144. {
  145. for (int port_index = 0; port_index < fNPorts; port_index++) {
  146. if (fPortBuffer[port_index]) {
  147. int res = opus_custom_decode_float(fOpusDecoder[port_index], fCompressedBuffer[port_index], fCompressedSizesByte[port_index], fPortBuffer[port_index], ((nframes == -1) ? fPeriodSize : nframes));
  148. if (res < 0 || res != ((nframes == -1) ? fPeriodSize : nframes)) {
  149. jack_error("opus_custom_decode_float error fCompressedSizeByte = %d res = %d", fCompressedSizesByte[port_index], res);
  150. }
  151. }
  152. }
  153. NextCycle();
  154. }
  155. //network<->buffer
  156. int NetOpusAudioBuffer::RenderFromNetwork(int cycle, int sub_cycle, uint32_t port_num)
  157. {
  158. // Cleanup all JACK ports at the beginning of the cycle
  159. if (sub_cycle == 0) {
  160. Cleanup();
  161. }
  162. if (port_num > 0) {
  163. if (sub_cycle == 0) {
  164. for (int port_index = 0; port_index < fNPorts; port_index++) {
  165. size_t len = *((size_t*)(fNetBuffer + port_index * fSubPeriodBytesSize));
  166. fCompressedSizesByte[port_index] = ntohs(len);
  167. memcpy(fCompressedBuffer[port_index] + sub_cycle * fSubPeriodBytesSize, fNetBuffer + CDO + port_index * fSubPeriodBytesSize, fSubPeriodBytesSize - CDO);
  168. }
  169. } else if (sub_cycle == fNumPackets - 1) {
  170. for (int port_index = 0; port_index < fNPorts; port_index++) {
  171. memcpy(fCompressedBuffer[port_index] + sub_cycle * fSubPeriodBytesSize - CDO, fNetBuffer + port_index * fLastSubPeriodBytesSize, fLastSubPeriodBytesSize);
  172. }
  173. } else {
  174. for (int port_index = 0; port_index < fNPorts; port_index++) {
  175. memcpy(fCompressedBuffer[port_index] + sub_cycle * fSubPeriodBytesSize - CDO, fNetBuffer + port_index * fSubPeriodBytesSize, fSubPeriodBytesSize);
  176. }
  177. }
  178. }
  179. return CheckPacket(cycle, sub_cycle);
  180. }
  181. int NetOpusAudioBuffer::RenderToNetwork(int sub_cycle, uint32_t port_num)
  182. {
  183. if (sub_cycle == 0) {
  184. for (int port_index = 0; port_index < fNPorts; port_index++) {
  185. unsigned short len = htons(fCompressedSizesByte[port_index]);
  186. memcpy(fNetBuffer + port_index * fSubPeriodBytesSize, &len, CDO);
  187. memcpy(fNetBuffer + port_index * fSubPeriodBytesSize + CDO, fCompressedBuffer[port_index], fSubPeriodBytesSize - CDO);
  188. }
  189. return fNPorts * fSubPeriodBytesSize;
  190. } else if (sub_cycle == fNumPackets - 1) {
  191. for (int port_index = 0; port_index < fNPorts; port_index++) {
  192. memcpy(fNetBuffer + port_index * fLastSubPeriodBytesSize, fCompressedBuffer[port_index] + sub_cycle * fSubPeriodBytesSize - CDO, fLastSubPeriodBytesSize);
  193. }
  194. return fNPorts * fLastSubPeriodBytesSize;
  195. } else {
  196. for (int port_index = 0; port_index < fNPorts; port_index++) {
  197. memcpy(fNetBuffer + port_index * fSubPeriodBytesSize, fCompressedBuffer[port_index] + sub_cycle * fSubPeriodBytesSize - CDO, fSubPeriodBytesSize);
  198. }
  199. return fNPorts * fSubPeriodBytesSize;
  200. }
  201. }
  202. }