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.

413 lines
9.7KB

  1. #include "global_pre.hpp"
  2. #include "audio.hpp"
  3. #include "util/common.hpp"
  4. #include "bridge.hpp"
  5. #include "global.hpp"
  6. namespace rack {
  7. AudioIO::AudioIO() {
  8. #ifdef USE_VST2
  9. setDriver(-1);
  10. #else
  11. setDriver(RtAudio::UNSPECIFIED);
  12. #endif
  13. }
  14. AudioIO::~AudioIO() {
  15. closeStream();
  16. }
  17. std::vector<int> AudioIO::getDrivers() {
  18. std::vector<int> drivers;
  19. #ifndef USE_VST2
  20. std::vector<RtAudio::Api> apis;
  21. RtAudio::getCompiledApi(apis);
  22. for (RtAudio::Api api : apis)
  23. drivers.push_back((int) api);
  24. // Add fake Bridge driver
  25. drivers.push_back(BRIDGE_DRIVER);
  26. #endif // !USE_VST2
  27. return drivers;
  28. }
  29. std::string AudioIO::getDriverName(int driver) {
  30. #ifndef USE_VST2
  31. switch (driver) {
  32. case RtAudio::UNSPECIFIED: return "Unspecified";
  33. case RtAudio::LINUX_ALSA: return "ALSA";
  34. case RtAudio::LINUX_PULSE: return "PulseAudio";
  35. case RtAudio::LINUX_OSS: return "OSS";
  36. case RtAudio::UNIX_JACK: return "JACK";
  37. case RtAudio::MACOSX_CORE: return "Core Audio";
  38. case RtAudio::WINDOWS_WASAPI: return "WASAPI";
  39. case RtAudio::WINDOWS_ASIO: return "ASIO";
  40. case RtAudio::WINDOWS_DS: return "DirectSound";
  41. case RtAudio::RTAUDIO_DUMMY: return "Dummy Audio";
  42. case BRIDGE_DRIVER: return "Bridge";
  43. default: return "Unknown";
  44. }
  45. #else
  46. return "VST";
  47. #endif // !USE_VST2
  48. }
  49. void AudioIO::setDriver(int driver) {
  50. // Close device
  51. setDevice(-1, 0);
  52. #ifndef USE_VST2
  53. // Close driver
  54. if (rtAudio) {
  55. delete rtAudio;
  56. rtAudio = NULL;
  57. }
  58. #endif // !USE_VST2
  59. this->driver = 0;
  60. #ifndef USE_VST2
  61. // Open driver
  62. if (driver >= 0) {
  63. rtAudio = new RtAudio((RtAudio::Api) driver);
  64. this->driver = (int) rtAudio->getCurrentApi();
  65. }
  66. else if (driver == BRIDGE_DRIVER) {
  67. this->driver = BRIDGE_DRIVER;
  68. }
  69. #endif // !USE_VST2
  70. }
  71. int AudioIO::getDeviceCount() {
  72. #ifndef USE_VST2
  73. if (rtAudio) {
  74. return rtAudio->getDeviceCount();
  75. }
  76. else if (driver == BRIDGE_DRIVER) {
  77. return BRIDGE_NUM_PORTS;
  78. }
  79. #endif // !USE_VST2
  80. return 0;
  81. }
  82. bool AudioIO::getDeviceInfo(int device, RtAudio::DeviceInfo *deviceInfo) {
  83. if (!deviceInfo)
  84. return false;
  85. #ifndef USE_VST2
  86. if (rtAudio) {
  87. if (device == this->device) {
  88. *deviceInfo = this->deviceInfo;
  89. return true;
  90. }
  91. else {
  92. try {
  93. *deviceInfo = rtAudio->getDeviceInfo(device);
  94. return true;
  95. }
  96. catch (RtAudioError &e) {
  97. warn("Failed to query RtAudio device: %s", e.what());
  98. }
  99. }
  100. }
  101. #endif // !USE_VST2
  102. return false;
  103. }
  104. int AudioIO::getDeviceChannels(int device) {
  105. if (device < 0)
  106. return 0;
  107. #ifndef USE_VST2
  108. if (rtAudio) {
  109. RtAudio::DeviceInfo deviceInfo;
  110. if (getDeviceInfo(device, &deviceInfo))
  111. return max((int) deviceInfo.inputChannels, (int) deviceInfo.outputChannels);
  112. }
  113. else if (driver == BRIDGE_DRIVER) {
  114. return max(BRIDGE_OUTPUTS, BRIDGE_INPUTS);
  115. }
  116. #endif // !USE_VST2
  117. return 0;
  118. }
  119. std::string AudioIO::getDeviceName(int device) {
  120. if (device < 0)
  121. return "";
  122. #ifndef USE_VST2
  123. if (rtAudio) {
  124. RtAudio::DeviceInfo deviceInfo;
  125. if (getDeviceInfo(device, &deviceInfo))
  126. return deviceInfo.name;
  127. }
  128. else if (driver == BRIDGE_DRIVER) {
  129. return stringf("%d", device + 1);
  130. }
  131. #endif // !USE_VST2
  132. return "";
  133. }
  134. std::string AudioIO::getDeviceDetail(int device, int offset) {
  135. if (device < 0)
  136. return "";
  137. #ifndef USE_VST2
  138. if (rtAudio) {
  139. RtAudio::DeviceInfo deviceInfo;
  140. if (getDeviceInfo(device, &deviceInfo)) {
  141. std::string deviceDetail = stringf("%s (", deviceInfo.name.c_str());
  142. if (offset < (int) deviceInfo.inputChannels)
  143. deviceDetail += stringf("%d-%d in", offset + 1, min(offset + maxChannels, (int) deviceInfo.inputChannels));
  144. if (offset < (int) deviceInfo.inputChannels && offset < (int) deviceInfo.outputChannels)
  145. deviceDetail += ", ";
  146. if (offset < (int) deviceInfo.outputChannels)
  147. deviceDetail += stringf("%d-%d out", offset + 1, min(offset + maxChannels, (int) deviceInfo.outputChannels));
  148. deviceDetail += ")";
  149. return deviceDetail;
  150. }
  151. }
  152. else if (driver == BRIDGE_DRIVER) {
  153. return stringf("Port %d", device + 1);
  154. }
  155. #endif // !USE_VST2
  156. return "";
  157. }
  158. void AudioIO::setDevice(int device, int offset) {
  159. closeStream();
  160. this->device = device;
  161. this->offset = offset;
  162. openStream();
  163. }
  164. std::vector<int> AudioIO::getSampleRates() {
  165. #ifndef USE_VST2
  166. if (rtAudio) {
  167. try {
  168. RtAudio::DeviceInfo deviceInfo = rtAudio->getDeviceInfo(device);
  169. std::vector<int> sampleRates(deviceInfo.sampleRates.begin(), deviceInfo.sampleRates.end());
  170. return sampleRates;
  171. }
  172. catch (RtAudioError &e) {
  173. warn("Failed to query RtAudio device: %s", e.what());
  174. }
  175. }
  176. #endif // !USE_VST2
  177. return {};
  178. }
  179. void AudioIO::setSampleRate(int sampleRate) {
  180. if (sampleRate == this->sampleRate)
  181. return;
  182. closeStream();
  183. this->sampleRate = sampleRate;
  184. openStream();
  185. }
  186. std::vector<int> AudioIO::getBlockSizes() {
  187. #ifdef USE_VST2
  188. return {};
  189. #else
  190. if (rtAudio) {
  191. return {64, 128, 256, 512, 1024, 2048, 4096};
  192. }
  193. return {};
  194. #endif
  195. }
  196. void AudioIO::setBlockSize(int blockSize) {
  197. if (blockSize == this->blockSize)
  198. return;
  199. closeStream();
  200. this->blockSize = blockSize;
  201. openStream();
  202. }
  203. void AudioIO::setChannels(int numOutputs, int numInputs) {
  204. this->numOutputs = numOutputs;
  205. this->numInputs = numInputs;
  206. onChannelsChange();
  207. }
  208. #ifndef USE_VST2
  209. static int rtCallback(void *outputBuffer, void *inputBuffer, unsigned int nFrames, double streamTime, RtAudioStreamStatus status, void *userData) {
  210. AudioIO *audioIO = (AudioIO*) userData;
  211. assert(audioIO);
  212. audioIO->processStream((const float *) inputBuffer, (float *) outputBuffer, nFrames);
  213. return 0;
  214. }
  215. #endif // !USE_VST2
  216. void AudioIO::openStream() {
  217. if (device < 0)
  218. return;
  219. #ifndef USE_VST2
  220. if (rtAudio) {
  221. // Open new device
  222. try {
  223. deviceInfo = rtAudio->getDeviceInfo(device);
  224. }
  225. catch (RtAudioError &e) {
  226. warn("Failed to query RtAudio device: %s", e.what());
  227. return;
  228. }
  229. if (rtAudio->isStreamOpen())
  230. return;
  231. setChannels(clamp((int) deviceInfo.outputChannels - offset, 0, maxChannels), clamp((int) deviceInfo.inputChannels - offset, 0, maxChannels));
  232. if (numOutputs == 0 && numInputs == 0) {
  233. warn("RtAudio device %d has 0 inputs and 0 outputs", device);
  234. return;
  235. }
  236. RtAudio::StreamParameters outParameters;
  237. outParameters.deviceId = device;
  238. outParameters.nChannels = numOutputs;
  239. outParameters.firstChannel = offset;
  240. RtAudio::StreamParameters inParameters;
  241. inParameters.deviceId = device;
  242. inParameters.nChannels = numInputs;
  243. inParameters.firstChannel = offset;
  244. RtAudio::StreamOptions options;
  245. options.flags |= RTAUDIO_JACK_DONT_CONNECT;
  246. options.streamName = "VCV Rack";
  247. int closestSampleRate = deviceInfo.preferredSampleRate;
  248. for (int sr : deviceInfo.sampleRates) {
  249. if (abs(sr - sampleRate) < abs(closestSampleRate - sampleRate)) {
  250. closestSampleRate = sr;
  251. }
  252. }
  253. try {
  254. info("Opening audio RtAudio device %d with %d in %d out", device, numInputs, numOutputs);
  255. rtAudio->openStream(
  256. numOutputs == 0 ? NULL : &outParameters,
  257. numInputs == 0 ? NULL : &inParameters,
  258. RTAUDIO_FLOAT32, closestSampleRate, (unsigned int*) &blockSize,
  259. &rtCallback, this, &options, NULL);
  260. }
  261. catch (RtAudioError &e) {
  262. warn("Failed to open RtAudio stream: %s", e.what());
  263. return;
  264. }
  265. try {
  266. info("Starting RtAudio stream %d", device);
  267. rtAudio->startStream();
  268. }
  269. catch (RtAudioError &e) {
  270. warn("Failed to start RtAudio stream: %s", e.what());
  271. return;
  272. }
  273. // Update sample rate because this may have changed
  274. this->sampleRate = rtAudio->getStreamSampleRate();
  275. onOpenStream();
  276. }
  277. else if (driver == BRIDGE_DRIVER) {
  278. setChannels(BRIDGE_OUTPUTS, BRIDGE_INPUTS);
  279. bridgeAudioSubscribe(device, this);
  280. }
  281. #endif // !USE_VST2
  282. }
  283. void AudioIO::closeStream() {
  284. setChannels(0, 0);
  285. #ifndef USE_VST2
  286. if (rtAudio) {
  287. if (rtAudio->isStreamRunning()) {
  288. info("Stopping RtAudio stream %d", device);
  289. try {
  290. rtAudio->stopStream();
  291. }
  292. catch (RtAudioError &e) {
  293. warn("Failed to stop RtAudio stream %s", e.what());
  294. }
  295. }
  296. if (rtAudio->isStreamOpen()) {
  297. info("Closing RtAudio stream %d", device);
  298. try {
  299. rtAudio->closeStream();
  300. }
  301. catch (RtAudioError &e) {
  302. warn("Failed to close RtAudio stream %s", e.what());
  303. }
  304. }
  305. deviceInfo = RtAudio::DeviceInfo();
  306. }
  307. else if (driver == BRIDGE_DRIVER) {
  308. bridgeAudioUnsubscribe(device, this);
  309. }
  310. #endif // !USE_VST2
  311. onCloseStream();
  312. }
  313. json_t *AudioIO::toJson() {
  314. json_t *rootJ = json_object();
  315. json_object_set_new(rootJ, "driver", json_integer(driver));
  316. std::string deviceName = getDeviceName(device);
  317. json_object_set_new(rootJ, "deviceName", json_string(deviceName.c_str()));
  318. json_object_set_new(rootJ, "offset", json_integer(offset));
  319. json_object_set_new(rootJ, "maxChannels", json_integer(maxChannels));
  320. json_object_set_new(rootJ, "sampleRate", json_integer(sampleRate));
  321. json_object_set_new(rootJ, "blockSize", json_integer(blockSize));
  322. return rootJ;
  323. }
  324. void AudioIO::fromJson(json_t *rootJ) {
  325. closeStream();
  326. json_t *driverJ = json_object_get(rootJ, "driver");
  327. if (driverJ)
  328. setDriver(json_number_value(driverJ));
  329. json_t *deviceNameJ = json_object_get(rootJ, "deviceName");
  330. if (deviceNameJ) {
  331. std::string deviceName = json_string_value(deviceNameJ);
  332. // Search for device ID with equal name
  333. for (int device = 0; device < getDeviceCount(); device++) {
  334. if (getDeviceName(device) == deviceName) {
  335. this->device = device;
  336. break;
  337. }
  338. }
  339. }
  340. json_t *offsetJ = json_object_get(rootJ, "offset");
  341. if (offsetJ)
  342. offset = json_integer_value(offsetJ);
  343. json_t *maxChannelsJ = json_object_get(rootJ, "maxChannels");
  344. if (maxChannelsJ)
  345. maxChannels = json_integer_value(maxChannelsJ);
  346. json_t *sampleRateJ = json_object_get(rootJ, "sampleRate");
  347. if (sampleRateJ)
  348. sampleRate = json_integer_value(sampleRateJ);
  349. json_t *blockSizeJ = json_object_get(rootJ, "blockSize");
  350. if (blockSizeJ)
  351. blockSize = json_integer_value(blockSizeJ);
  352. openStream();
  353. }
  354. } // namespace rack