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.

108 lines
2.7KB

  1. #pragma once
  2. #include "common.hpp"
  3. #include "engine/Light.hpp"
  4. namespace rack {
  5. namespace engine {
  6. static const int PORT_MAX_CHANNELS = 16;
  7. struct alignas(32) Port {
  8. /** Voltage of the port. */
  9. union {
  10. /** Unstable API. Use getVoltage() and setVoltage() instead. */
  11. float voltages[PORT_MAX_CHANNELS] = {};
  12. /** DEPRECATED. Unstable API. Use getVoltage() and setVoltage() instead. */
  13. float value;
  14. };
  15. /** Number of polyphonic channels
  16. Unstable API. Use set/getChannels() instead.
  17. May be 0 to PORT_MAX_CHANNELS.
  18. */
  19. uint8_t channels = 1;
  20. /** Unstable API. Use isConnected() instead. */
  21. bool active = false;
  22. /** For rendering plug lights on cables.
  23. Green for positive, red for negative, and blue for polyphonic.
  24. */
  25. Light plugLights[3];
  26. void setVoltage(float voltage, int channel = 0) {
  27. voltages[channel] = voltage;
  28. }
  29. /** Returns the voltage of the given channel.
  30. Because of proper bookkeeping, all channels higher than the input port's number of channels should be 0V.
  31. */
  32. float getVoltage(int channel = 0) {
  33. return voltages[channel];
  34. }
  35. /** Returns the given channel's voltage if the port is polyphonic, otherwise returns the first voltage (channel 0). */
  36. float getPolyVoltage(int channel) {
  37. return (channels == 1) ? getVoltage(0) : getVoltage(channel);
  38. }
  39. /** Returns the voltage if a cable is connected, otherwise returns the given normal voltage. */
  40. float getNormalVoltage(float normalVoltage, int channel = 0) {
  41. return isConnected() ? getVoltage(channel) : normalVoltage;
  42. }
  43. float getNormalPolyVoltage(float normalVoltage, int channel) {
  44. return isConnected() ? getPolyVoltage(channel) : normalVoltage;
  45. }
  46. /** Reads all voltage values from an array of size `channels` */
  47. void setVoltages(const float *voltages) {
  48. for (int c = 0; c < channels; c++) {
  49. this->voltages[c] = voltages[c];
  50. }
  51. }
  52. /** Writes all voltage values to an array of size `channels` */
  53. void getVoltages(float *voltages) {
  54. for (int c = 0; c < channels; c++) {
  55. voltages[c] = this->voltages[c];
  56. }
  57. }
  58. /** Sets the number of polyphony channels. */
  59. void setChannels(int channels) {
  60. // Set higher channel voltages to 0
  61. for (int c = channels; c < this->channels; c++) {
  62. voltages[c] = 0.f;
  63. }
  64. this->channels = channels;
  65. }
  66. int getChannels() {
  67. return channels;
  68. }
  69. /** Returns if a cable is connected to the Port.
  70. You can use this for skipping code that generates output voltages.
  71. */
  72. bool isConnected() {
  73. return active;
  74. }
  75. void process(float deltaTime);
  76. /** Use getNormalVoltage() instead. */
  77. DEPRECATED float normalize(float normalVoltage) {
  78. return getNormalVoltage(normalVoltage);
  79. }
  80. };
  81. struct Output : Port {};
  82. struct Input : Port {};
  83. } // namespace engine
  84. } // namespace rack