Collection of tools useful for audio production
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.

301 lines
8.1KB

  1. /*
  2. * Carla Backend
  3. * Copyright (C) 2012 Filipe Coelho <falktx@gmail.com>
  4. *
  5. * This program is free software; you can redistribute it and/or modify
  6. * it under the terms of the GNU General Public License as published by
  7. * the Free Software Foundation; either version 2 of the License, or
  8. * any later version.
  9. *
  10. * This program is distributed in the hope that it will be useful,
  11. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  12. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  13. * GNU General Public License for more details.
  14. *
  15. * For a full copy of the GNU General Public License see the COPYING file
  16. */
  17. #ifdef CARLA_ENGINE_RTAUDIO
  18. #include "carla_engine.h"
  19. #include "carla_plugin.h"
  20. CARLA_BACKEND_START_NAMESPACE
  21. #if 0
  22. } /* adjust editor indent */
  23. #endif
  24. // -------------------------------------------------------------------------------------------------------------------
  25. // static RtAudio<->Engine calls
  26. static int carla_rtaudio_process_callback(void* outputBuffer, void* inputBuffer, unsigned int nframes, double streamTime, RtAudioStreamStatus status, void* userData)
  27. {
  28. CarlaEngineRtAudio* const engine = (CarlaEngineRtAudio*)userData;
  29. engine->handleProcessCallback(outputBuffer, inputBuffer, nframes, streamTime, status);
  30. return 0;
  31. }
  32. // -------------------------------------------------------------------------------------------------------------------
  33. // Carla Engine (RtAudio)
  34. CarlaEngineRtAudio::CarlaEngineRtAudio(RtAudio::Api api)
  35. : CarlaEngine(),
  36. adac(api)
  37. {
  38. qDebug("CarlaEngineRtAudio::CarlaEngineRtAudio()");
  39. type = CarlaEngineTypeRtAudio;
  40. procThread = nullptr;
  41. }
  42. CarlaEngineRtAudio::~CarlaEngineRtAudio()
  43. {
  44. qDebug("CarlaEngineRtAudio::~CarlaEngineRtAudio()");
  45. }
  46. bool CarlaEngineRtAudio::init(const char* const clientName)
  47. {
  48. qDebug("CarlaEngineRtAudio::init(\"%s\")", clientName);
  49. procThread = nullptr;
  50. if (adac.getDeviceCount() < 1)
  51. {
  52. setLastError("No audio devices available");
  53. return false;
  54. }
  55. sampleRate = 48000;
  56. unsigned int rtBufferFrames = 512;
  57. RtAudio::StreamParameters iParams, oParams;
  58. //iParams.deviceId = 3;
  59. //oParams.deviceId = 2;
  60. iParams.nChannels = 2;
  61. oParams.nChannels = 2;
  62. RtAudio::StreamOptions options;
  63. options.flags = /*RTAUDIO_NONINTERLEAVED |*/ RTAUDIO_MINIMIZE_LATENCY /*| RTAUDIO_HOG_DEVICE*/ | RTAUDIO_SCHEDULE_REALTIME | RTAUDIO_ALSA_USE_DEFAULT;
  64. options.streamName = clientName;
  65. options.priority = 85;
  66. try {
  67. adac.openStream(&oParams, &iParams, RTAUDIO_FLOAT32, sampleRate, &rtBufferFrames, carla_rtaudio_process_callback, this, &options);
  68. }
  69. catch (RtError& e)
  70. {
  71. setLastError(e.what());
  72. return false;
  73. }
  74. bufferSize = rtBufferFrames;
  75. name = strdup(clientName);
  76. qDebug("RtAudio bufferSize = %i", bufferSize);
  77. try {
  78. adac.startStream();
  79. }
  80. catch (RtError& e)
  81. {
  82. setLastError(e.what());
  83. return false;
  84. }
  85. CarlaEngine::init(name);
  86. return true;
  87. }
  88. bool CarlaEngineRtAudio::close()
  89. {
  90. qDebug("CarlaEngineRtAudio::close()");
  91. CarlaEngine::close();
  92. if (name)
  93. {
  94. free((void*)name);
  95. name = nullptr;
  96. }
  97. if (adac.isStreamRunning())
  98. adac.stopStream();
  99. if (adac.isStreamOpen())
  100. adac.closeStream();
  101. return true;
  102. }
  103. bool CarlaEngineRtAudio::isOnAudioThread()
  104. {
  105. return (QThread::currentThread() == procThread);
  106. }
  107. bool CarlaEngineRtAudio::isOffline()
  108. {
  109. return false;
  110. }
  111. bool CarlaEngineRtAudio::isRunning()
  112. {
  113. return adac.isStreamRunning();
  114. }
  115. CarlaEngineClient* CarlaEngineRtAudio::addClient(CarlaPlugin* const plugin)
  116. {
  117. CarlaEngineClientNativeHandle handle;
  118. return new CarlaEngineClient(CarlaEngineTypeRtAudio, handle);
  119. Q_UNUSED(plugin);
  120. }
  121. // -------------------------------------------------------------------------------------------------------------------
  122. void CarlaEngineRtAudio::handleProcessCallback(void* outputBuffer, void* inputBuffer, unsigned int nframes, double streamTime, RtAudioStreamStatus status)
  123. {
  124. if (procThread == nullptr)
  125. procThread = QThread::currentThread();
  126. // get buffers from RtAudio
  127. float* insPtr = (float*)inputBuffer;
  128. float* outsPtr = (float*)outputBuffer;
  129. // assert buffers
  130. Q_ASSERT(insPtr);
  131. Q_ASSERT(outsPtr);
  132. // create temporary audio buffers
  133. float ains_tmp_buf1[nframes];
  134. float ains_tmp_buf2[nframes];
  135. float aouts_tmp_buf1[nframes];
  136. float aouts_tmp_buf2[nframes];
  137. float* ains_tmp[2] = { ains_tmp_buf1, ains_tmp_buf2 };
  138. float* aouts_tmp[2] = { aouts_tmp_buf1, aouts_tmp_buf2 };
  139. // initialize audio input
  140. for (unsigned int i=0; i < nframes*2; i++)
  141. {
  142. if (i % 2)
  143. ains_tmp_buf2[i/2] = insPtr[i];
  144. else
  145. ains_tmp_buf1[i/2] = insPtr[i];
  146. }
  147. // initialize control input
  148. memset(rackControlEventsIn, 0, sizeof(CarlaEngineControlEvent)*MAX_ENGINE_CONTROL_EVENTS);
  149. {
  150. // TODO
  151. }
  152. // initialize midi input
  153. memset(rackMidiEventsIn, 0, sizeof(CarlaEngineMidiEvent)*MAX_ENGINE_MIDI_EVENTS);
  154. {
  155. // TODO
  156. }
  157. // initialize outputs (zero)
  158. memset(aouts_tmp_buf1, 0, sizeof(float)*nframes);
  159. memset(aouts_tmp_buf2, 0, sizeof(float)*nframes);
  160. memset(rackControlEventsOut, 0, sizeof(CarlaEngineControlEvent)*MAX_ENGINE_CONTROL_EVENTS);
  161. memset(rackMidiEventsOut, 0, sizeof(CarlaEngineMidiEvent)*MAX_ENGINE_MIDI_EVENTS);
  162. bool processed = false;
  163. // process plugins
  164. for (unsigned short i=0; i < MAX_PLUGINS; i++)
  165. {
  166. CarlaPlugin* const plugin = getPluginUnchecked(i);
  167. if (plugin && plugin->enabled())
  168. {
  169. if (processed)
  170. {
  171. // initialize inputs (from previous outputs)
  172. memcpy(ains_tmp_buf1, aouts_tmp_buf1, sizeof(float)*nframes);
  173. memcpy(ains_tmp_buf2, aouts_tmp_buf2, sizeof(float)*nframes);
  174. memcpy(rackMidiEventsIn, rackMidiEventsOut, sizeof(CarlaEngineMidiEvent)*MAX_ENGINE_MIDI_EVENTS);
  175. // initialize outputs (zero)
  176. memset(aouts_tmp_buf1, 0, sizeof(float)*nframes);
  177. memset(aouts_tmp_buf2, 0, sizeof(float)*nframes);
  178. memset(rackMidiEventsOut, 0, sizeof(CarlaEngineMidiEvent)*MAX_ENGINE_MIDI_EVENTS);
  179. }
  180. // process
  181. plugin->engineProcessLock();
  182. plugin->initBuffers();
  183. if (carlaOptions.proccess_hp)
  184. {
  185. float* ains_buffer2[2];
  186. float* aouts_buffer2[2];
  187. for (uint32_t j=0; j < nframes; j += 8)
  188. {
  189. ains_buffer2[0] = ains_tmp_buf1 + j;
  190. ains_buffer2[1] = ains_tmp_buf2 + j;
  191. aouts_buffer2[0] = aouts_tmp_buf1 + j;
  192. aouts_buffer2[1] = aouts_tmp_buf2 + j;
  193. plugin->process(ains_buffer2, aouts_buffer2, 8, j);
  194. }
  195. }
  196. else
  197. plugin->process(ains_tmp, aouts_tmp, nframes);
  198. plugin->engineProcessUnlock();
  199. // if plugin has no audio inputs, add previous buffers
  200. if (plugin->audioInCount() == 0)
  201. {
  202. for (uint32_t j=0; j < nframes; j++)
  203. {
  204. aouts_tmp_buf1[j] += ains_tmp_buf1[j];
  205. aouts_tmp_buf2[j] += ains_tmp_buf2[j];
  206. }
  207. }
  208. processed = true;
  209. }
  210. }
  211. // if no plugins in the rack, copy inputs over outputs
  212. if (! processed)
  213. {
  214. memcpy(aouts_tmp_buf1, ains_tmp_buf1, sizeof(float)*nframes);
  215. memcpy(aouts_tmp_buf2, ains_tmp_buf2, sizeof(float)*nframes);
  216. memcpy(rackMidiEventsOut, rackMidiEventsIn, sizeof(CarlaEngineMidiEvent)*MAX_ENGINE_MIDI_EVENTS);
  217. }
  218. // output audio
  219. for (unsigned int i=0; i < nframes*2; i++)
  220. {
  221. if (i % 2)
  222. outsPtr[i] = aouts_tmp_buf2[i/2];
  223. else
  224. outsPtr[i] = aouts_tmp_buf1[i/2];
  225. }
  226. // output control
  227. {
  228. // TODO
  229. }
  230. // output midi
  231. {
  232. // TODO
  233. }
  234. Q_UNUSED(streamTime);
  235. Q_UNUSED(status);
  236. }
  237. CARLA_BACKEND_END_NAMESPACE
  238. #endif // CARLA_ENGINE_RTAUDIO