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.

236 lines
5.3KB

  1. #include <audio.hpp>
  2. #include <string.hpp>
  3. namespace rack {
  4. namespace audio {
  5. static std::vector<std::pair<int, Driver*>> drivers;
  6. static std::string getDetailTemplate(std::string name, int numInputs, int numOutputs, int offset, int maxChannels) {
  7. std::string text = name;
  8. text += " (";
  9. if (offset < numInputs) {
  10. text += string::f("%d-%d in", offset + 1, std::min(offset + maxChannels, numInputs));
  11. }
  12. if (offset < numInputs && offset < numOutputs) {
  13. text += ", ";
  14. }
  15. if (offset < numOutputs) {
  16. text += string::f("%d-%d out", offset + 1, std::min(offset + maxChannels, numOutputs));
  17. }
  18. text += ")";
  19. return text;
  20. }
  21. ////////////////////
  22. // Driver
  23. ////////////////////
  24. std::string Driver::getDeviceDetail(int deviceId, int offset, int maxChannels) {
  25. if (deviceId < 0)
  26. return "";
  27. return getDetailTemplate(getDeviceName(deviceId), getDeviceNumInputs(deviceId), getDeviceNumOutputs(deviceId), offset, maxChannels);
  28. }
  29. ////////////////////
  30. // Device
  31. ////////////////////
  32. void Device::subscribe(Port* port) {
  33. subscribed.insert(port);
  34. }
  35. void Device::unsubscribe(Port* port) {
  36. auto it = subscribed.find(port);
  37. if (it != subscribed.end())
  38. subscribed.erase(it);
  39. }
  40. std::string Device::getDetail(int offset, int maxChannels) {
  41. return getDetailTemplate(getName(), getNumInputs(), getNumOutputs(), offset, maxChannels);
  42. }
  43. void Device::processBuffer(const float* input, int inputStride, float* output, int outputStride, int frames) {
  44. for (Port* port : subscribed) {
  45. // Setting the thread context should probably be the responsibility of Port, but because processInput() etc are overridden, this is the only good place for it.
  46. contextSet(port->context);
  47. port->processInput(input + port->offset, inputStride, frames);
  48. }
  49. for (Port* port : subscribed) {
  50. contextSet(port->context);
  51. port->processBuffer(input + port->offset, inputStride, output + port->offset, outputStride, frames);
  52. }
  53. for (Port* port : subscribed) {
  54. contextSet(port->context);
  55. port->processOutput(output + port->offset, outputStride, frames);
  56. }
  57. }
  58. void Device::onOpenStream() {
  59. for (Port* port : subscribed) {
  60. contextSet(port->context);
  61. port->onOpenStream();
  62. }
  63. }
  64. void Device::onCloseStream() {
  65. for (Port* port : subscribed) {
  66. contextSet(port->context);
  67. port->onCloseStream();
  68. }
  69. }
  70. ////////////////////
  71. // Port
  72. ////////////////////
  73. Port::Port() {
  74. context = contextGet();
  75. reset();
  76. }
  77. Port::~Port() {
  78. setDriverId(-1);
  79. }
  80. void Port::reset() {
  81. setDriverId(-1);
  82. offset = 0;
  83. }
  84. void Port::setDriverId(int driverId) {
  85. // Unset device and driver
  86. setDeviceId(-1);
  87. driver = NULL;
  88. this->driverId = -1;
  89. // Find driver by ID
  90. driver = audio::getDriver(driverId);
  91. if (driver) {
  92. this->driverId = driverId;
  93. }
  94. else {
  95. // Set first driver as default
  96. driver = drivers[0].second;
  97. this->driverId = drivers[0].first;
  98. }
  99. }
  100. void Port::setDeviceId(int deviceId) {
  101. // Destroy device
  102. if (driver && this->deviceId >= 0) {
  103. driver->unsubscribe(this->deviceId, this);
  104. }
  105. device = NULL;
  106. this->deviceId = -1;
  107. // Create device
  108. if (driver && deviceId >= 0) {
  109. device = driver->subscribe(deviceId, this);
  110. this->deviceId = deviceId;
  111. }
  112. }
  113. int Port::getNumInputs() {
  114. if (!device)
  115. return 0;
  116. return std::min(device->getNumInputs() - offset, maxChannels);
  117. }
  118. int Port::getNumOutputs() {
  119. if (!device)
  120. return 0;
  121. return std::min(device->getNumOutputs() - offset, maxChannels);
  122. }
  123. json_t* Port::toJson() {
  124. json_t* rootJ = json_object();
  125. json_object_set_new(rootJ, "driver", json_integer(getDriverId()));
  126. if (device) {
  127. std::string deviceName = device->getName();
  128. json_object_set_new(rootJ, "deviceName", json_string(deviceName.c_str()));
  129. }
  130. json_object_set_new(rootJ, "sampleRate", json_integer(getSampleRate()));
  131. json_object_set_new(rootJ, "blockSize", json_integer(getBlockSize()));
  132. json_object_set_new(rootJ, "offset", json_integer(offset));
  133. return rootJ;
  134. }
  135. void Port::fromJson(json_t* rootJ) {
  136. setDriverId(-1);
  137. json_t* driverJ = json_object_get(rootJ, "driver");
  138. if (driverJ)
  139. setDriverId(json_number_value(driverJ));
  140. if (driver) {
  141. json_t* deviceNameJ = json_object_get(rootJ, "deviceName");
  142. if (deviceNameJ) {
  143. std::string deviceName = json_string_value(deviceNameJ);
  144. // Search for device ID with equal name
  145. for (int deviceId : driver->getDeviceIds()) {
  146. if (driver->getDeviceName(deviceId) == deviceName) {
  147. setDeviceId(deviceId);
  148. break;
  149. }
  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. std::vector<int> getDriverIds() {
  179. std::vector<int> driverIds;
  180. for (auto& pair : drivers) {
  181. driverIds.push_back(pair.first);
  182. }
  183. return driverIds;
  184. }
  185. Driver* getDriver(int driverId) {
  186. for (auto& pair : drivers) {
  187. if (pair.first == driverId)
  188. return pair.second;
  189. }
  190. return NULL;
  191. }
  192. } // namespace audio
  193. } // namespace rack