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.

216 lines
4.6KB

  1. #include <audio.hpp>
  2. #include <string.hpp>
  3. namespace rack {
  4. namespace audio {
  5. static std::vector<std::pair<int, Driver*>> drivers;
  6. ////////////////////
  7. // Device
  8. ////////////////////
  9. void Device::subscribe(Port* port) {
  10. subscribed.insert(port);
  11. }
  12. void Device::unsubscribe(Port* port) {
  13. auto it = subscribed.find(port);
  14. if (it != subscribed.end())
  15. subscribed.erase(it);
  16. }
  17. void Device::processBuffer(const float* input, int inputStride, float* output, int outputStride, int frames) {
  18. for (Port* port : subscribed) {
  19. port->processInput(input + port->offset, inputStride, frames);
  20. }
  21. for (Port* port : subscribed) {
  22. port->processBuffer(input + port->offset, inputStride, output + port->offset, outputStride, frames);
  23. }
  24. for (Port* port : subscribed) {
  25. port->processOutput(output + port->offset, outputStride, frames);
  26. }
  27. }
  28. void Device::onOpenStream() {
  29. for (Port* port : subscribed) {
  30. port->onOpenStream();
  31. }
  32. }
  33. void Device::onCloseStream() {
  34. for (Port* port : subscribed) {
  35. port->onCloseStream();
  36. }
  37. }
  38. ////////////////////
  39. // Port
  40. ////////////////////
  41. Port::Port() {
  42. setDriverId(-1);
  43. }
  44. Port::~Port() {
  45. setDriverId(-1);
  46. }
  47. std::vector<int> Port::getDriverIds() {
  48. std::vector<int> driverIds;
  49. for (auto& pair : drivers) {
  50. driverIds.push_back(pair.first);
  51. }
  52. return driverIds;
  53. }
  54. void Port::setDriverId(int driverId) {
  55. // Unset device and driver
  56. setDeviceId(-1);
  57. driver = NULL;
  58. this->driverId = -1;
  59. if (driverId == -1) {
  60. // Set first driver as default
  61. if (!drivers.empty()) {
  62. driver = drivers[0].second;
  63. this->driverId = drivers[0].first;
  64. }
  65. }
  66. else {
  67. // Set driver with driverId
  68. for (auto& pair : drivers) {
  69. if (pair.first == driverId) {
  70. driver = pair.second;
  71. this->driverId = driverId;
  72. break;
  73. }
  74. }
  75. }
  76. }
  77. std::string Port::getDriverName(int driverId) {
  78. for (auto& pair : drivers) {
  79. if (pair.first == driverId) {
  80. return pair.second->getName();
  81. }
  82. }
  83. return "";
  84. }
  85. void Port::setDeviceId(int deviceId) {
  86. // Destroy device
  87. if (driver && this->deviceId >= 0) {
  88. driver->unsubscribe(this->deviceId, this);
  89. }
  90. device = NULL;
  91. this->deviceId = -1;
  92. // Create device
  93. if (driver && deviceId >= 0) {
  94. device = driver->subscribe(deviceId, this);
  95. this->deviceId = deviceId;
  96. }
  97. }
  98. std::string Port::getDeviceDetail(int deviceId, int offset) {
  99. if (!driver || !device)
  100. return "";
  101. std::string text = getDeviceName(getDeviceId());
  102. text += " (";
  103. int numInputs = device->getNumInputs();
  104. int numOutputs = device->getNumOutputs();
  105. if (offset < numInputs) {
  106. text += string::f("%d-%d in", offset + 1, std::min(offset + maxChannels, numInputs));
  107. }
  108. if (offset < numInputs && offset < numOutputs) {
  109. text += ", ";
  110. }
  111. if (offset < numOutputs) {
  112. text += string::f("%d-%d out", offset + 1, std::min(offset + maxChannels, numOutputs));
  113. }
  114. text += ")";
  115. return text;
  116. }
  117. int Port::getNumInputs() {
  118. if (!device)
  119. return 0;
  120. return std::min(device->getNumInputs() - offset, maxChannels);
  121. }
  122. int Port::getNumOutputs() {
  123. if (!device)
  124. return 0;
  125. return std::min(device->getNumOutputs() - offset, maxChannels);
  126. }
  127. json_t* Port::toJson() {
  128. json_t* rootJ = json_object();
  129. json_object_set_new(rootJ, "driver", json_integer(getDriverId()));
  130. std::string deviceName = getDeviceName(getDeviceId());
  131. if (!deviceName.empty())
  132. json_object_set_new(rootJ, "deviceName", json_string(deviceName.c_str()));
  133. json_object_set_new(rootJ, "sampleRate", json_integer(getSampleRate()));
  134. json_object_set_new(rootJ, "blockSize", json_integer(getBlockSize()));
  135. json_object_set_new(rootJ, "offset", json_integer(offset));
  136. return rootJ;
  137. }
  138. void Port::fromJson(json_t* rootJ) {
  139. json_t* driverJ = json_object_get(rootJ, "driver");
  140. if (driverJ)
  141. setDriverId(json_number_value(driverJ));
  142. json_t* deviceNameJ = json_object_get(rootJ, "deviceName");
  143. if (deviceNameJ) {
  144. std::string deviceName = json_string_value(deviceNameJ);
  145. // Search for device ID with equal name
  146. for (int deviceId : getDeviceIds()) {
  147. if (getDeviceName(deviceId) == deviceName) {
  148. setDeviceId(deviceId);
  149. break;
  150. }
  151. }
  152. }
  153. json_t* sampleRateJ = json_object_get(rootJ, "sampleRate");
  154. if (sampleRateJ)
  155. setSampleRate(json_integer_value(sampleRateJ));
  156. json_t* blockSizeJ = json_object_get(rootJ, "blockSize");
  157. if (blockSizeJ)
  158. setBlockSize(json_integer_value(blockSizeJ));
  159. json_t* offsetJ = json_object_get(rootJ, "offset");
  160. if (offsetJ)
  161. offset = json_integer_value(offsetJ);
  162. }
  163. ////////////////////
  164. // audio
  165. ////////////////////
  166. void init() {
  167. }
  168. void destroy() {
  169. for (auto& pair : drivers) {
  170. delete pair.second;
  171. }
  172. drivers.clear();
  173. }
  174. void addDriver(int driverId, Driver* driver) {
  175. assert(driver);
  176. drivers.push_back(std::make_pair(driverId, driver));
  177. }
  178. } // namespace audio
  179. } // namespace rack