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.

245 lines
6.3KB

  1. /*
  2. * Carla Backend
  3. * Copyright (C) 2012 Filipe Coelho <falktx@falktx.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. // -------------------------------------------------------------------------------------------------------------------
  22. // static RtAudio<->Engine calls
  23. static int carla_rtaudio_process_callback(void* outputBuffer, void* inputBuffer, unsigned int nframes, double streamTime, RtAudioStreamStatus status, void* userData)
  24. {
  25. CarlaEngineRtAudio* const engine = (CarlaEngineRtAudio*)userData;
  26. engine->handleProcessCallback(outputBuffer, inputBuffer, nframes, streamTime, status);
  27. return 0;
  28. }
  29. // -------------------------------------------------------------------------------------------------------------------
  30. // Carla Engine (RtAudio)
  31. CarlaEngineRtAudio::CarlaEngineRtAudio(RtAudio::Api api)
  32. : CarlaEngine(),
  33. adac(api)
  34. {
  35. qDebug("CarlaEngineRtAudio::CarlaEngineRtAudio()");
  36. type = CarlaEngineTypeRtAudio;
  37. }
  38. CarlaEngineRtAudio::~CarlaEngineRtAudio()
  39. {
  40. qDebug("CarlaEngineRtAudio::~CarlaEngineRtAudio()");
  41. }
  42. bool CarlaEngineRtAudio::init(const char* const clientName)
  43. {
  44. qDebug("CarlaEngineRtAudio::init(\"%s\")", clientName);
  45. if (adac.getDeviceCount() < 1)
  46. {
  47. setLastError("No audio devices available");
  48. return false;
  49. }
  50. sampleRate = 48000;
  51. unsigned int rtBufferFrames = 512;
  52. RtAudio::StreamParameters iParams, oParams;
  53. //iParams.deviceId = 3;
  54. //oParams.deviceId = 2;
  55. iParams.nChannels = 2;
  56. oParams.nChannels = 2;
  57. RtAudio::StreamOptions options;
  58. options.flags = /*RTAUDIO_NONINTERLEAVED |*/ RTAUDIO_MINIMIZE_LATENCY /*| RTAUDIO_HOG_DEVICE*/ | RTAUDIO_SCHEDULE_REALTIME | RTAUDIO_ALSA_USE_DEFAULT;
  59. options.streamName = clientName;
  60. options.priority = 85;
  61. try {
  62. adac.openStream(&oParams, &iParams, RTAUDIO_FLOAT32, sampleRate, &rtBufferFrames, carla_rtaudio_process_callback, this, &options);
  63. }
  64. catch (RtError& e)
  65. {
  66. setLastError(e.what());
  67. return false;
  68. }
  69. bufferSize = rtBufferFrames;
  70. // set client name, fixed for OSC usage
  71. // FIXME - put this in shared?
  72. char* fixedName = strdup(clientName);
  73. for (size_t i=0; i < strlen(fixedName); i++)
  74. {
  75. if (! (std::isalpha(fixedName[i]) || std::isdigit(fixedName[i])))
  76. fixedName[i] = '_';
  77. }
  78. name = strdup(fixedName);
  79. free((void*)fixedName);
  80. qDebug("RtAudio bufferSize = %i", bufferSize);
  81. try {
  82. adac.startStream();
  83. }
  84. catch (RtError& e)
  85. {
  86. setLastError(e.what());
  87. return false;
  88. }
  89. CarlaEngine::init(name);
  90. return true;
  91. }
  92. bool CarlaEngineRtAudio::close()
  93. {
  94. qDebug("CarlaEngineRtAudio::close()");
  95. CarlaEngine::close();
  96. if (name)
  97. {
  98. free((void*)name);
  99. name = nullptr;
  100. }
  101. if (adac.isStreamRunning())
  102. adac.stopStream();
  103. if (adac.isStreamOpen())
  104. adac.closeStream();
  105. return true;
  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. handle.type = type;
  119. // unsigned int rtBufferFrames = getBufferSize();
  120. // RtAudio::StreamParameters iParams, oParams;
  121. // iParams.nChannels = plugin->audioInCount();
  122. // oParams.nChannels = plugin->audioOutCount();
  123. // RtAudio::StreamOptions options;
  124. // options.flags = /*RTAUDIO_NONINTERLEAVED |*/ RTAUDIO_MINIMIZE_LATENCY /*| RTAUDIO_HOG_DEVICE*/ | RTAUDIO_SCHEDULE_REALTIME | RTAUDIO_ALSA_USE_DEFAULT;
  125. // options.streamName = plugin->name();
  126. // options.priority = 85;
  127. // try {
  128. // adac.openStream(&oParams, &iParams, RTAUDIO_FLOAT32, getSampleRate(), &rtBufferFrames, carla_rtaudio_process_callback, this, &options);
  129. // }
  130. // catch (RtError& e)
  131. // {
  132. // setLastError(e.what());
  133. // return false;
  134. // }
  135. return new CarlaEngineClient(handle);
  136. Q_UNUSED(plugin);
  137. }
  138. // -------------------------------------------------------------------------------------------------------------------
  139. void CarlaEngineRtAudio::handleProcessCallback(void* outputBuffer, void* inputBuffer, unsigned int nframes, double streamTime, RtAudioStreamStatus status)
  140. {
  141. if (maxPluginNumber() == 0)
  142. return;
  143. // get buffers from RtAudio
  144. float* insPtr = (float*)inputBuffer;
  145. float* outsPtr = (float*)outputBuffer;
  146. // assert buffers
  147. CARLA_ASSERT(insPtr);
  148. CARLA_ASSERT(outsPtr);
  149. // create temporary audio buffers
  150. float inBuf1[nframes];
  151. float inBuf2[nframes];
  152. float outBuf1[nframes];
  153. float outBuf2[nframes];
  154. // initialize audio input
  155. for (unsigned int i=0; i < nframes*2; i++)
  156. {
  157. if (i % 2)
  158. inBuf2[i/2] = insPtr[i];
  159. else
  160. inBuf1[i/2] = insPtr[i];
  161. }
  162. // create (real) audio buffers
  163. float* inBuf[2] = { inBuf1, inBuf2 };
  164. float* outBuf[2] = { outBuf1, outBuf2 };
  165. // initialize control input
  166. memset(rackControlEventsIn, 0, sizeof(CarlaEngineControlEvent)*MAX_ENGINE_CONTROL_EVENTS);
  167. {
  168. // TODO
  169. }
  170. // initialize midi input
  171. memset(rackMidiEventsIn, 0, sizeof(CarlaEngineMidiEvent)*MAX_ENGINE_MIDI_EVENTS);
  172. {
  173. // TODO
  174. }
  175. processRack(inBuf, outBuf, nframes);
  176. // output audio
  177. for (unsigned int i=0; i < nframes*2; i++)
  178. {
  179. if (i % 2)
  180. outsPtr[i] = outBuf2[i/2];
  181. else
  182. outsPtr[i] = outBuf1[i/2];
  183. }
  184. // output control
  185. {
  186. // TODO
  187. }
  188. // output midi
  189. {
  190. // TODO
  191. }
  192. Q_UNUSED(streamTime);
  193. Q_UNUSED(status);
  194. }
  195. CARLA_BACKEND_END_NAMESPACE
  196. #endif // CARLA_ENGINE_RTAUDIO