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.

338 lines
14KB

  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. #include "common.hpp"
  18. #include "CarlaHost.h"
  19. #include "CarlaBackendUtils.hpp"
  20. // -------------------------------------------------------------------------------------------------------------------
  21. static bool gEngineRunning = false;
  22. void engine_idle_handler()
  23. {
  24. if (gEngineRunning)
  25. carla_engine_idle();
  26. }
  27. // -------------------------------------------------------------------------------------------------------------------
  28. static void EngineCallback(void* ptr, EngineCallbackOpcode action, uint pluginId, int value1, int value2, float value3, const char* valueStr)
  29. {
  30. carla_stdout("EngineCallback(%p, %u:%s, %u, %i, %i, %f, %s)",
  31. ptr, (uint)action, EngineCallbackOpcode2Str(action), pluginId, value1, value2, value3, valueStr);
  32. char msgBuf[1024];
  33. std::snprintf(msgBuf, 1023, "Carla: %u %u %i %i %f %s\n", action, pluginId, value1, value2, value3, valueStr);
  34. msgBuf[1023] = '\0';
  35. switch (action)
  36. {
  37. case ENGINE_CALLBACK_ENGINE_STARTED:
  38. gEngineRunning = true;
  39. break;
  40. case ENGINE_CALLBACK_ENGINE_STOPPED:
  41. case ENGINE_CALLBACK_QUIT:
  42. gEngineRunning = false;
  43. break;
  44. default:
  45. break;
  46. }
  47. send_server_side_message(msgBuf);
  48. }
  49. static const char* FileCallback(void* ptr, FileCallbackOpcode action, bool isDir, const char* title, const char* filter)
  50. {
  51. carla_stdout("FileCallback(%p, %u:%s, %s, %s, %s)",
  52. ptr, (uint)action, FileCallbackOpcode(action), bool2str(isDir), title, filter);
  53. char msgBuf[1024];
  54. std::snprintf(msgBuf, 1023, "fc %u %i \"%s\" \"%s\"", action, isDir, title, filter);
  55. msgBuf[1023] = '\0';
  56. send_server_side_message(msgBuf);
  57. // FIXME, need to wait for response!
  58. return nullptr;
  59. }
  60. // -------------------------------------------------------------------------------------------------------------------
  61. void handle_carla_get_engine_driver_count(const std::shared_ptr<Session> session)
  62. {
  63. const char* const buf = str_buf_uint(carla_get_engine_driver_count());
  64. session->close(OK, buf, { { "Content-Length", size_buf(buf) } } );
  65. }
  66. void handle_carla_get_engine_driver_name(const std::shared_ptr<Session> session)
  67. {
  68. const std::shared_ptr<const Request> request = session->get_request();
  69. const int index = std::atoi(request->get_path_parameter("index").c_str());
  70. CARLA_SAFE_ASSERT_RETURN(index >= 0 /*&& index < INT_MAX*/,)
  71. const char* const buf = str_buf_string(carla_get_engine_driver_name(index));
  72. session->close(OK, buf, { { "Content-Length", size_buf(buf) } } );
  73. }
  74. void handle_carla_get_engine_driver_device_names(const std::shared_ptr<Session> session)
  75. {
  76. const std::shared_ptr<const Request> request = session->get_request();
  77. const int index = std::atoi(request->get_path_parameter("index").c_str());
  78. CARLA_SAFE_ASSERT_RETURN(index >= 0 /*&& index < INT_MAX*/,)
  79. const char* const buf = str_buf_string_array(carla_get_engine_driver_device_names(index));
  80. session->close(OK, buf, { { "Content-Length", size_buf(buf) } } );
  81. }
  82. void handle_carla_get_engine_driver_device_info(const std::shared_ptr<Session> session)
  83. {
  84. const std::shared_ptr<const Request> request = session->get_request();
  85. const int index = std::atoi(request->get_path_parameter("index").c_str());
  86. CARLA_SAFE_ASSERT_RETURN(index >= 0 /*&& index < INT_MAX*/,)
  87. const std::string name = request->get_path_parameter("name");
  88. const EngineDriverDeviceInfo* const info = carla_get_engine_driver_device_info(index, name.c_str());
  89. char* jsonBuf;
  90. jsonBuf = json_buf_start();
  91. jsonBuf = json_buf_add_uint(jsonBuf, "hints", info->hints);
  92. jsonBuf = json_buf_add_uint_array(jsonBuf, "bufferSizes", info->bufferSizes);
  93. jsonBuf = json_buf_add_float_array(jsonBuf, "sampleRates", info->sampleRates);
  94. const char* const buf = json_buf_end(jsonBuf);
  95. session->close(OK, buf, { { "Content-Length", size_buf(buf) } } );
  96. }
  97. // -------------------------------------------------------------------------------------------------------------------
  98. void handle_carla_engine_init(const std::shared_ptr<Session> session)
  99. {
  100. // setup callbacks
  101. carla_set_engine_callback(EngineCallback, nullptr);
  102. carla_set_file_callback(FileCallback, nullptr);
  103. // handle request now
  104. const std::shared_ptr<const Request> request = session->get_request();
  105. const std::string driverName = request->get_path_parameter("driverName");
  106. const std::string clientName = request->get_path_parameter("clientName");
  107. const bool resp = carla_engine_init(driverName.c_str(), clientName.c_str());
  108. session->close(resp ? OK : BAD_REQUEST);
  109. }
  110. void handle_carla_engine_close(const std::shared_ptr<Session> session)
  111. {
  112. const bool resp = carla_engine_close();
  113. session->close(resp ? OK : BAD_REQUEST);
  114. }
  115. void handle_carla_is_engine_running(const std::shared_ptr<Session> session)
  116. {
  117. const bool resp = carla_is_engine_running();
  118. session->close(resp ? OK : BAD_REQUEST);
  119. }
  120. void handle_carla_set_engine_about_to_close(const std::shared_ptr<Session> session)
  121. {
  122. const bool resp = carla_set_engine_about_to_close();
  123. session->close(resp ? OK : BAD_REQUEST);
  124. }
  125. // -------------------------------------------------------------------------------------------------------------------
  126. void carla_set_engine_option(EngineOption option, int value, const char* valueStr);
  127. // -------------------------------------------------------------------------------------------------------------------
  128. bool carla_load_file(const char* filename);
  129. bool carla_load_project(const char* filename);
  130. bool carla_save_project(const char* filename);
  131. // -------------------------------------------------------------------------------------------------------------------
  132. bool carla_patchbay_connect(uint groupIdA, uint portIdA, uint groupIdB, uint portIdB);
  133. bool carla_patchbay_disconnect(uint connectionId);
  134. bool carla_patchbay_refresh(bool external);
  135. // -------------------------------------------------------------------------------------------------------------------
  136. void handle_carla_transport_play(const std::shared_ptr<Session> session)
  137. {
  138. carla_transport_play();
  139. session->close(OK);
  140. }
  141. void handle_carla_transport_pause(const std::shared_ptr<Session> session)
  142. {
  143. carla_transport_pause();
  144. session->close(OK);
  145. }
  146. void handle_carla_transport_bpm(const std::shared_ptr<Session> session)
  147. {
  148. const std::shared_ptr<const Request> request = session->get_request();
  149. const double bpm = std::atof(request->get_path_parameter("bpm").c_str());
  150. CARLA_SAFE_ASSERT_RETURN(bpm > 0.0,) // FIXME
  151. carla_transport_bpm(bpm);
  152. session->close(OK);
  153. }
  154. void handle_carla_transport_relocate(const std::shared_ptr<Session> session)
  155. {
  156. const std::shared_ptr<const Request> request = session->get_request();
  157. const long int frame = std::atol(request->get_path_parameter("frame").c_str());
  158. CARLA_SAFE_ASSERT_RETURN(frame >= 0,)
  159. carla_transport_relocate(frame);
  160. session->close(OK);
  161. }
  162. void handle_carla_get_current_transport_frame(const std::shared_ptr<Session> session)
  163. {
  164. const char* const buf = str_buf_uint64(carla_get_current_transport_frame());
  165. session->close(OK, buf, { { "Content-Length", size_buf(buf) } } );
  166. }
  167. void handle_carla_get_transport_info(const std::shared_ptr<Session> session)
  168. {
  169. const CarlaTransportInfo* const info = carla_get_transport_info();
  170. char* jsonBuf;
  171. jsonBuf = json_buf_start();
  172. jsonBuf = json_buf_add_bool(jsonBuf, "playing", info->playing);
  173. jsonBuf = json_buf_add_uint64(jsonBuf, "frame", info->frame);
  174. jsonBuf = json_buf_add_int(jsonBuf, "bar", info->bar);
  175. jsonBuf = json_buf_add_int(jsonBuf, "beat", info->beat);
  176. jsonBuf = json_buf_add_int(jsonBuf, "tick", info->tick);
  177. jsonBuf = json_buf_add_float(jsonBuf, "bpm", info->bpm);
  178. const char* const buf = json_buf_end(jsonBuf);
  179. session->close(OK, buf, { { "Content-Length", size_buf(buf) } } );
  180. }
  181. // -------------------------------------------------------------------------------------------------------------------
  182. uint32_t carla_get_current_plugin_count();
  183. uint32_t carla_get_max_plugin_number();
  184. bool carla_add_plugin(BinaryType btype, PluginType ptype,
  185. const char* filename, const char* name, const char* label, int64_t uniqueId,
  186. const void* extraPtr, uint options);
  187. bool carla_remove_plugin(uint pluginId);
  188. bool carla_remove_all_plugins();
  189. // -------------------------------------------------------------------------------------------------------------------
  190. const char* carla_rename_plugin(uint pluginId, const char* newName);
  191. bool carla_clone_plugin(uint pluginId);
  192. bool carla_replace_plugin(uint pluginId);
  193. bool carla_switch_plugins(uint pluginIdA, uint pluginIdB);
  194. // -------------------------------------------------------------------------------------------------------------------
  195. bool carla_load_plugin_state(uint pluginId, const char* filename);
  196. bool carla_save_plugin_state(uint pluginId, const char* filename);
  197. bool carla_export_plugin_lv2(uint pluginId, const char* lv2path);
  198. // -------------------------------------------------------------------------------------------------------------------
  199. const CarlaPluginInfo* carla_get_plugin_info(uint pluginId);
  200. const CarlaPortCountInfo* carla_get_audio_port_count_info(uint pluginId);
  201. const CarlaPortCountInfo* carla_get_midi_port_count_info(uint pluginId);
  202. const CarlaPortCountInfo* carla_get_parameter_count_info(uint pluginId);
  203. const CarlaParameterInfo* carla_get_parameter_info(uint pluginId, uint32_t parameterId);
  204. const CarlaScalePointInfo* carla_get_parameter_scalepoint_info(uint pluginId, uint32_t parameterId, uint32_t scalePointId);
  205. const ParameterData* carla_get_parameter_data(uint pluginId, uint32_t parameterId);
  206. const ParameterRanges* carla_get_parameter_ranges(uint pluginId, uint32_t parameterId);
  207. const MidiProgramData* carla_get_midi_program_data(uint pluginId, uint32_t midiProgramId);
  208. const CustomData* carla_get_custom_data(uint pluginId, uint32_t customDataId);
  209. const char* carla_get_chunk_data(uint pluginId);
  210. // -------------------------------------------------------------------------------------------------------------------
  211. uint32_t carla_get_parameter_count(uint pluginId);
  212. uint32_t carla_get_program_count(uint pluginId);
  213. uint32_t carla_get_midi_program_count(uint pluginId);
  214. uint32_t carla_get_custom_data_count(uint pluginId);
  215. const char* carla_get_parameter_text(uint pluginId, uint32_t parameterId);
  216. const char* carla_get_program_name(uint pluginId, uint32_t programId);
  217. const char* carla_get_midi_program_name(uint pluginId, uint32_t midiProgramId);
  218. const char* carla_get_real_plugin_name(uint pluginId);
  219. int32_t carla_get_current_program_index(uint pluginId);
  220. int32_t carla_get_current_midi_program_index(uint pluginId);
  221. float carla_get_default_parameter_value(uint pluginId, uint32_t parameterId);
  222. float carla_get_current_parameter_value(uint pluginId, uint32_t parameterId);
  223. float carla_get_internal_parameter_value(uint pluginId, int32_t parameterId);
  224. float carla_get_input_peak_value(uint pluginId, bool isLeft);
  225. float carla_get_output_peak_value(uint pluginId, bool isLeft);
  226. // -------------------------------------------------------------------------------------------------------------------
  227. void carla_set_active(uint pluginId, bool onOff);
  228. void carla_set_drywet(uint pluginId, float value);
  229. void carla_set_volume(uint pluginId, float value);
  230. void carla_set_balance_left(uint pluginId, float value);
  231. void carla_set_balance_right(uint pluginId, float value);
  232. void carla_set_panning(uint pluginId, float value);
  233. void carla_set_ctrl_channel(uint pluginId, int8_t channel);
  234. void carla_set_option(uint pluginId, uint option, bool yesNo);
  235. // -------------------------------------------------------------------------------------------------------------------
  236. void carla_set_parameter_value(uint pluginId, uint32_t parameterId, float value);
  237. void carla_set_parameter_midi_channel(uint pluginId, uint32_t parameterId, uint8_t channel);
  238. void carla_set_parameter_midi_cc(uint pluginId, uint32_t parameterId, int16_t cc);
  239. void carla_set_program(uint pluginId, uint32_t programId);
  240. void carla_set_midi_program(uint pluginId, uint32_t midiProgramId);
  241. void carla_set_custom_data(uint pluginId, const char* type, const char* key, const char* value);
  242. void carla_set_chunk_data(uint pluginId, const char* chunkData);
  243. // -------------------------------------------------------------------------------------------------------------------
  244. void carla_prepare_for_save(uint pluginId);
  245. void carla_reset_parameters(uint pluginId);
  246. void carla_randomize_parameters(uint pluginId);
  247. // -------------------------------------------------------------------------------------------------------------------
  248. void carla_send_midi_note(uint pluginId, uint8_t channel, uint8_t note, uint8_t velocity);
  249. // -------------------------------------------------------------------------------------------------------------------
  250. uint32_t carla_get_buffer_size();
  251. double carla_get_sample_rate();
  252. void handle_carla_get_last_error(const std::shared_ptr<Session> session)
  253. {
  254. const char* const buf = carla_get_last_error();
  255. session->close(OK, buf, { { "Content-Length", size_buf(buf) } } );
  256. }
  257. const char* carla_get_host_osc_url_tcp();
  258. const char* carla_get_host_osc_url_udp();
  259. // -------------------------------------------------------------------------------------------------------------------