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.

138 lines
4.5KB

  1. #pragma once
  2. #include <vector>
  3. #include <common.hpp>
  4. #include <engine/Module.hpp>
  5. #include <engine/Cable.hpp>
  6. #include <engine/ParamHandle.hpp>
  7. namespace rack {
  8. namespace engine {
  9. /** Manages Modules and Cables and steps them in time.
  10. All methods are thread-safe and can safely be called from anywhere.
  11. The methods clear, addModule, removeModule, moduleToJson, moduleFromJson, addCable, removeCable, addParamHandle, removeParamHandle, toJson, and fromJson cannot be run simultaneously with any other Engine method.
  12. Calling these methods inside any Engine method will result in a deadlock.
  13. */
  14. struct Engine {
  15. struct Internal;
  16. Internal* internal;
  17. Engine();
  18. ~Engine();
  19. /** Removes all modules and cables. */
  20. void clear();
  21. /** Advances the engine by `frames` frames.
  22. Only call this method from the primary module.
  23. */
  24. void stepBlock(int frames);
  25. void setPrimaryModule(Module* module);
  26. Module* getPrimaryModule();
  27. /** Returns the sample rate used by the engine for stepping each module.
  28. */
  29. float getSampleRate();
  30. /** Returns the inverse of the current sample rate.
  31. */
  32. float getSampleTime();
  33. /** Causes worker threads to block on a mutex instead of spinlock.
  34. Call this in your Module::stepBlock() method to hint that the operation will take more than ~0.1 ms.
  35. */
  36. void yieldWorkers();
  37. /** Returns the number of stepBlock() calls since the Engine was created.
  38. */
  39. int64_t getBlock();
  40. /** Returns the number of audio samples since the Engine was created.
  41. */
  42. int64_t getFrame();
  43. /** Returns the estimated time corresponding to the current frame, based on the time of when stepBlock() was last called.
  44. Calculated by `stepTime + framesSinceStep / sampleRate`.
  45. */
  46. double getFrameTime();
  47. /** Returns the frame when stepBlock() was last called.
  48. */
  49. int64_t getBlockFrame();
  50. /** Returns the time in seconds when stepBlock() was last called.
  51. */
  52. double getBlockTime();
  53. /** Returns the total number of frames in the current stepBlock() call.
  54. */
  55. int getBlockFrames();
  56. /** Returns the total time that stepBlock() is advancing, in seconds.
  57. Calculated by `stepFrames / sampleRate`.
  58. */
  59. double getBlockDuration();
  60. // Modules
  61. size_t getNumModules();
  62. /** Fills `moduleIds` with up to `len` module IDs in the rack.
  63. Returns the number of IDs written.
  64. This C-like method does no allocations. The vector C++ version below does.
  65. */
  66. size_t getModuleIds(int64_t* moduleIds, size_t len);
  67. std::vector<int64_t> getModuleIds();
  68. /** Adds a module to the rack engine.
  69. The module ID must not be taken by another module.
  70. If the module ID is -1, an ID is automatically assigned.
  71. Does not transfer pointer ownership.
  72. */
  73. void addModule(Module* module);
  74. void removeModule(Module* module);
  75. Module* getModule(int64_t moduleId);
  76. void resetModule(Module* module);
  77. void randomizeModule(Module* module);
  78. void bypassModule(Module* module, bool bypass);
  79. /** Serializes/deserializes with locking, ensuring that Module::process() is not called during toJson()/fromJson().
  80. */
  81. json_t* moduleToJson(Module* module);
  82. void moduleFromJson(Module* module, json_t* rootJ);
  83. // Cables
  84. size_t getNumCables();
  85. size_t getCableIds(int64_t* cableIds, size_t len);
  86. std::vector<int64_t> getCableIds();
  87. /** Adds a cable to the rack engine.
  88. The cable ID must not be taken by another cable.
  89. If the cable ID is -1, an ID is automatically assigned.
  90. Does not transfer pointer ownership.
  91. */
  92. void addCable(Cable* cable);
  93. void removeCable(Cable* cable);
  94. Cable* getCable(int64_t cableId);
  95. // Params
  96. void setParam(Module* module, int paramId, float value);
  97. float getParam(Module* module, int paramId);
  98. /** Requests the parameter to smoothly change toward `value`.
  99. */
  100. void setSmoothParam(Module* module, int paramId, float value);
  101. /** Returns the target value before smoothing.
  102. */
  103. float getSmoothParam(Module* module, int paramId);
  104. // ParamHandles
  105. void addParamHandle(ParamHandle* paramHandle);
  106. void removeParamHandle(ParamHandle* paramHandle);
  107. /** Returns the unique ParamHandle for the given paramId
  108. */
  109. ParamHandle* getParamHandle(int64_t moduleId, int paramId);
  110. /** Use getParamHandle(moduleId, paramId) instead. */
  111. DEPRECATED ParamHandle* getParamHandle(Module* module, int paramId);
  112. /** Sets the ParamHandle IDs and module pointer.
  113. If `overwrite` is true and another ParamHandle points to the same param, unsets that one and replaces it with the given handle.
  114. */
  115. void updateParamHandle(ParamHandle* paramHandle, int64_t moduleId, int paramId, bool overwrite = true);
  116. json_t* toJson();
  117. void fromJson(json_t* rootJ);
  118. };
  119. } // namespace engine
  120. } // namespace rack