Audio plugin host https://kx.studio/carla
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.

248 lines
12KB

  1. /*
  2. * Carla REST API Server
  3. * Copyright (C) 2018 Filipe Coelho <falktx@falktx.com>
  4. *
  5. * This program is free software; you can redistribute it and/or
  6. * modify it under the terms of the GNU General Public License as
  7. * published by the Free Software Foundation; either version 2 of
  8. * the License, or 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 doc/GPL.txt file.
  16. */
  17. /* NOTE
  18. * Even though Carla is GPL, restbed if AGPL.
  19. * As such, the resulting binary will be AGPL.
  20. * Take this into consideration before deploying it to any servers.
  21. */
  22. #include "common.hpp"
  23. #include "carla-host.cpp"
  24. #include "carla-utils.cpp"
  25. #include "CarlaMutex.hpp"
  26. #include "CarlaStringList.hpp"
  27. // -------------------------------------------------------------------------------------------------------------------
  28. std::vector<std::shared_ptr<Session>> gSessions;
  29. CarlaStringList gSessionMessages;
  30. CarlaMutex gSessionMessagesMutex;
  31. // -------------------------------------------------------------------------------------------------------------------
  32. void send_server_side_message(const char* const message)
  33. {
  34. const CarlaMutexLocker cml(gSessionMessagesMutex);
  35. gSessionMessages.append(message);
  36. }
  37. // -------------------------------------------------------------------------------------------------------------------
  38. static void register_server_side_handler(const std::shared_ptr<Session> session)
  39. {
  40. const auto headers = std::multimap<std::string, std::string> {
  41. { "Connection", "keep-alive" },
  42. { "Cache-Control", "no-cache" },
  43. { "Content-Type", "text/event-stream" },
  44. { "Access-Control-Allow-Origin", "*" } //Only required for demo purposes.
  45. };
  46. session->yield(OK, headers, [](const std::shared_ptr<Session> rsession) {
  47. gSessions.push_back(rsession);
  48. });
  49. }
  50. static void event_stream_handler(void)
  51. {
  52. static bool firstInit = true;
  53. if (firstInit)
  54. {
  55. firstInit = false;
  56. carla_stdout("Carla REST-API Server started");
  57. }
  58. gSessions.erase(
  59. std::remove_if(gSessions.begin(), gSessions.end(),
  60. [](const std::shared_ptr<Session> &a) {
  61. return a->is_closed();
  62. }),
  63. gSessions.end());
  64. CarlaStringList messages;
  65. {
  66. const CarlaMutexLocker cml(gSessionMessagesMutex);
  67. if (gSessionMessages.count() > 0)
  68. gSessionMessages.moveTo(messages);
  69. }
  70. for (auto message : messages)
  71. {
  72. // std::puts(message);
  73. for (auto session : gSessions)
  74. session->yield(OK, message);
  75. }
  76. }
  77. // -------------------------------------------------------------------------------------------------------------------
  78. static void make_resource(Service& service,
  79. const char* const path,
  80. const std::function<void (const std::shared_ptr<Session>)>& callback)
  81. {
  82. std::shared_ptr<Resource> resource = std::make_shared<Resource>();
  83. resource->set_path(path);
  84. resource->set_method_handler("GET", callback);
  85. service.publish(resource);
  86. }
  87. // -------------------------------------------------------------------------------------------------------------------
  88. int main(int, const char**)
  89. {
  90. Service service;
  91. // server-side messages
  92. {
  93. std::shared_ptr<Resource> resource = std::make_shared<Resource>();
  94. resource->set_path("/stream");
  95. resource->set_method_handler("GET", register_server_side_handler);
  96. service.publish(resource);
  97. }
  98. // carla-host
  99. make_resource(service, "/get_engine_driver_count", handle_carla_get_engine_driver_count);
  100. make_resource(service, "/get_engine_driver_name", handle_carla_get_engine_driver_name);
  101. make_resource(service, "/get_engine_driver_device_names", handle_carla_get_engine_driver_device_names);
  102. make_resource(service, "/get_engine_driver_device_info", handle_carla_get_engine_driver_device_info);
  103. make_resource(service, "/engine_init", handle_carla_engine_init);
  104. make_resource(service, "/engine_close", handle_carla_engine_close);
  105. make_resource(service, "/is_engine_running", handle_carla_is_engine_running);
  106. make_resource(service, "/set_engine_about_to_close", handle_carla_set_engine_about_to_close);
  107. make_resource(service, "/set_engine_option", handle_carla_set_engine_option);
  108. make_resource(service, "/load_file", handle_carla_load_file);
  109. make_resource(service, "/load_project", handle_carla_load_project);
  110. make_resource(service, "/save_project", handle_carla_save_project);
  111. make_resource(service, "/patchbay_connect", handle_carla_patchbay_connect);
  112. make_resource(service, "/patchbay_disconnect", handle_carla_patchbay_disconnect);
  113. make_resource(service, "/patchbay_refresh", handle_carla_patchbay_refresh);
  114. make_resource(service, "/transport_play", handle_carla_transport_play);
  115. make_resource(service, "/transport_pause", handle_carla_transport_pause);
  116. make_resource(service, "/transport_bpm", handle_carla_transport_bpm);
  117. make_resource(service, "/transport_relocate", handle_carla_transport_relocate);
  118. make_resource(service, "/get_current_transport_frame", handle_carla_get_current_transport_frame);
  119. make_resource(service, "/get_transport_info", handle_carla_get_transport_info);
  120. make_resource(service, "/get_current_plugin_count", handle_carla_get_current_plugin_count);
  121. make_resource(service, "/get_max_plugin_number", handle_carla_get_max_plugin_number);
  122. make_resource(service, "/add_plugin", handle_carla_add_plugin);
  123. make_resource(service, "/remove_plugin", handle_carla_remove_plugin);
  124. make_resource(service, "/remove_all_plugins", handle_carla_remove_all_plugins);
  125. make_resource(service, "/rename_plugin", handle_carla_rename_plugin);
  126. make_resource(service, "/clone_plugin", handle_carla_clone_plugin);
  127. make_resource(service, "/replace_plugin", handle_carla_replace_plugin);
  128. make_resource(service, "/switch_plugins", handle_carla_switch_plugins);
  129. make_resource(service, "/load_plugin_state", handle_carla_load_plugin_state);
  130. make_resource(service, "/save_plugin_state", handle_carla_save_plugin_state);
  131. make_resource(service, "/export_plugin_lv2", handle_carla_export_plugin_lv2);
  132. make_resource(service, "/get_plugin_info", handle_carla_get_plugin_info);
  133. make_resource(service, "/get_audio_port_count_info", handle_carla_get_audio_port_count_info);
  134. make_resource(service, "/get_midi_port_count_info", handle_carla_get_midi_port_count_info);
  135. make_resource(service, "/get_parameter_count_info", handle_carla_get_parameter_count_info);
  136. make_resource(service, "/get_parameter_info", handle_carla_get_parameter_info);
  137. make_resource(service, "/get_parameter_scalepoint_info", handle_carla_get_parameter_scalepoint_info);
  138. make_resource(service, "/get_parameter_data", handle_carla_get_parameter_data);
  139. make_resource(service, "/get_parameter_ranges", handle_carla_get_parameter_ranges);
  140. make_resource(service, "/get_midi_program_data", handle_carla_get_midi_program_data);
  141. make_resource(service, "/get_custom_data", handle_carla_get_custom_data);
  142. make_resource(service, "/get_custom_data_value", handle_carla_get_custom_data_value);
  143. make_resource(service, "/get_chunk_data", handle_carla_get_chunk_data);
  144. make_resource(service, "/get_parameter_count", handle_carla_get_parameter_count);
  145. make_resource(service, "/get_program_count", handle_carla_get_program_count);
  146. make_resource(service, "/get_midi_program_count", handle_carla_get_midi_program_count);
  147. make_resource(service, "/get_custom_data_count", handle_carla_get_custom_data_count);
  148. make_resource(service, "/get_parameter_text", handle_carla_get_parameter_text);
  149. make_resource(service, "/get_program_name", handle_carla_get_program_name);
  150. make_resource(service, "/get_midi_program_name", handle_carla_get_midi_program_name);
  151. make_resource(service, "/get_real_plugin_name", handle_carla_get_real_plugin_name);
  152. make_resource(service, "/get_current_program_index", handle_carla_get_current_program_index);
  153. make_resource(service, "/get_current_midi_program_index", handle_carla_get_current_midi_program_index);
  154. make_resource(service, "/get_default_parameter_value", handle_carla_get_default_parameter_value);
  155. make_resource(service, "/get_current_parameter_value", handle_carla_get_current_parameter_value);
  156. make_resource(service, "/get_internal_parameter_value", handle_carla_get_internal_parameter_value);
  157. make_resource(service, "/get_input_peak_value", handle_carla_get_input_peak_value);
  158. make_resource(service, "/get_output_peak_value", handle_carla_get_output_peak_value);
  159. make_resource(service, "/set_active", handle_carla_set_active);
  160. make_resource(service, "/set_drywet", handle_carla_set_drywet);
  161. make_resource(service, "/set_volume", handle_carla_set_volume);
  162. make_resource(service, "/set_balance_left", handle_carla_set_balance_left);
  163. make_resource(service, "/set_balance_right", handle_carla_set_balance_right);
  164. make_resource(service, "/set_panning", handle_carla_set_panning);
  165. make_resource(service, "/set_ctrl_channel", handle_carla_set_ctrl_channel);
  166. make_resource(service, "/set_option", handle_carla_set_option);
  167. make_resource(service, "/set_parameter_value", handle_carla_set_parameter_value);
  168. make_resource(service, "/set_parameter_midi_channel", handle_carla_set_parameter_midi_channel);
  169. make_resource(service, "/set_parameter_midi_cc", handle_carla_set_parameter_midi_cc);
  170. make_resource(service, "/set_program", handle_carla_set_program);
  171. make_resource(service, "/set_midi_program", handle_carla_set_midi_program);
  172. make_resource(service, "/set_custom_data", handle_carla_set_custom_data);
  173. make_resource(service, "/set_chunk_data", handle_carla_set_chunk_data);
  174. make_resource(service, "/prepare_for_save", handle_carla_prepare_for_save);
  175. make_resource(service, "/reset_parameters", handle_carla_reset_parameters);
  176. make_resource(service, "/randomize_parameters", handle_carla_randomize_parameters);
  177. make_resource(service, "/send_midi_note", handle_carla_send_midi_note);
  178. make_resource(service, "/get_buffer_size", handle_carla_get_buffer_size);
  179. make_resource(service, "/get_sample_rate", handle_carla_get_sample_rate);
  180. make_resource(service, "/get_last_error", handle_carla_get_last_error);
  181. make_resource(service, "/get_host_osc_url_tcp", handle_carla_get_host_osc_url_tcp);
  182. make_resource(service, "/get_host_osc_url_udp", handle_carla_get_host_osc_url_udp);
  183. // carla-utils
  184. make_resource(service, "/get_complete_license_text", handle_carla_get_complete_license_text);
  185. make_resource(service, "/get_supported_file_extensions", handle_carla_get_supported_file_extensions);
  186. make_resource(service, "/get_supported_features", handle_carla_get_supported_features);
  187. make_resource(service, "/get_cached_plugin_count", handle_carla_get_cached_plugin_count);
  188. make_resource(service, "/get_cached_plugin_info", handle_carla_get_cached_plugin_info);
  189. // schedule events
  190. service.schedule(engine_idle_handler); // FIXME, crashes on fast times, but we need ~30Hz for OSC..
  191. service.schedule(event_stream_handler, std::chrono::milliseconds(500));
  192. std::shared_ptr<Settings> settings = std::make_shared<Settings>();
  193. settings->set_port(2228);
  194. settings->set_default_header("Connection", "close");
  195. service.start(settings);
  196. return 0;
  197. }
  198. // -------------------------------------------------------------------------------------------------------------------