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.

137 lines
4.0KB

  1. #pragma once
  2. #include <stdint.h>
  3. #include <functional>
  4. #include "../globals.h"
  5. //Expected upper bound of synths given that max polyphony is hit
  6. #define EXPECTED_USAGE 3
  7. struct LegatoParams;
  8. class NotePool
  9. {
  10. public:
  11. typedef uint8_t note_t;
  12. //Currently this wastes a ton of bits due ot the legatoMirror flag
  13. struct NoteDescriptor {
  14. //acceptable overlap after 2 minutes
  15. //run time at 48kHz 8 samples per buffer
  16. //19 bit minimum
  17. uint32_t age;
  18. uint8_t note;
  19. uint8_t sendto;
  20. //max of 16 kit elms and 3 kit items per
  21. uint8_t size;
  22. uint8_t status;
  23. bool legatoMirror;
  24. bool operator==(NoteDescriptor);
  25. //status checks
  26. bool playing(void) const;
  27. bool off(void) const;
  28. bool sustained(void) const;
  29. bool released(void) const;
  30. //status transitions
  31. void setStatus(uint8_t s);
  32. void doSustain(void);
  33. bool canSustain(void) const;
  34. void makeUnsustainable(void);
  35. };
  36. //To be pedantic this wastes 2 or 6 bytes per descriptor
  37. //depending on 32bit/64bit alignment rules
  38. struct SynthDescriptor {
  39. SynthNote *note;
  40. uint8_t type;
  41. uint8_t kit;
  42. };
  43. //Pool of notes
  44. NoteDescriptor ndesc[POLYPHONY];
  45. SynthDescriptor sdesc[POLYPHONY*EXPECTED_USAGE];
  46. bool needs_cleaning;
  47. //Iterators
  48. struct activeNotesIter {
  49. SynthDescriptor *begin() {return _b;};
  50. SynthDescriptor *end() {return _e;};
  51. SynthDescriptor *_b;
  52. SynthDescriptor *_e;
  53. };
  54. struct activeDescIter {
  55. activeDescIter(NotePool &_np):np(_np)
  56. {
  57. int off=0;
  58. for(int i=0; i<POLYPHONY; ++i, ++off)
  59. if(np.ndesc[i].status == 0)
  60. break;
  61. _end = np.ndesc+off;
  62. }
  63. NoteDescriptor *begin() {return np.ndesc;};
  64. NoteDescriptor *end() { return _end; };
  65. NoteDescriptor *_end;
  66. NotePool &np;
  67. };
  68. struct constActiveDescIter {
  69. constActiveDescIter(const NotePool &_np):np(_np)
  70. {
  71. int off=0;
  72. for(int i=0; i<POLYPHONY; ++i, ++off)
  73. if(np.ndesc[i].status == 0)
  74. break;
  75. _end = np.ndesc+off;
  76. }
  77. const NoteDescriptor *begin() const {return np.ndesc;};
  78. const NoteDescriptor *end() const { return _end; };
  79. const NoteDescriptor *_end;
  80. const NotePool &np;
  81. };
  82. activeNotesIter activeNotes(NoteDescriptor &n);
  83. activeDescIter activeDesc(void);
  84. constActiveDescIter activeDesc(void) const;
  85. //Counts of descriptors used for tests
  86. int usedNoteDesc(void) const;
  87. int usedSynthDesc(void) const;
  88. NotePool(void);
  89. //Operations
  90. void insertNote(uint8_t note, uint8_t sendto, SynthDescriptor desc, bool legato=false);
  91. void insertLegatoNote(uint8_t note, uint8_t sendto, SynthDescriptor desc);
  92. void upgradeToLegato(void);
  93. void applyLegato(LegatoParams &par);
  94. void makeUnsustainable(uint8_t note);
  95. bool full(void) const;
  96. bool synthFull(int sdesc_count) const;
  97. //Note that isn't KEY_PLAYING or KEY_RELASED_AND_SUSTAINING
  98. bool existsRunningNote(void) const;
  99. int getRunningNotes(void) const;
  100. void enforceKeyLimit(int limit);
  101. void releasePlayingNotes(void);
  102. void releaseNote(note_t note);
  103. void release(NoteDescriptor &d);
  104. void killAllNotes(void);
  105. void killNote(note_t note);
  106. void kill(NoteDescriptor &d);
  107. void kill(SynthDescriptor &s);
  108. void entomb(NoteDescriptor &d);
  109. void cleanup(void);
  110. void dump(void);
  111. };