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.

117 lines
3.4KB

  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. };
  26. //To be pedantic this wastes 2 or 6 bytes per descriptor
  27. //depending on 32bit/64bit alignment rules
  28. struct SynthDescriptor {
  29. SynthNote *note;
  30. uint8_t type;
  31. uint8_t kit;
  32. };
  33. //Pool of notes
  34. NoteDescriptor ndesc[POLYPHONY];
  35. SynthDescriptor sdesc[POLYPHONY*EXPECTED_USAGE];
  36. bool needs_cleaning;
  37. //Iterators
  38. struct activeNotesIter {
  39. SynthDescriptor *begin() {return _b;};
  40. SynthDescriptor *end() {return _e;};
  41. SynthDescriptor *_b;
  42. SynthDescriptor *_e;
  43. };
  44. struct activeDescIter {
  45. activeDescIter(NotePool &_np):np(_np)
  46. {
  47. int off=0;
  48. for(int i=0; i<POLYPHONY; ++i, ++off)
  49. if(np.ndesc[i].status == 0)
  50. break;
  51. _end = np.ndesc+off;
  52. }
  53. NoteDescriptor *begin() {return np.ndesc;};
  54. NoteDescriptor *end() { return _end; };
  55. NoteDescriptor *_end;
  56. NotePool &np;
  57. };
  58. struct constActiveDescIter {
  59. constActiveDescIter(const NotePool &_np):np(_np)
  60. {
  61. int off=0;
  62. for(int i=0; i<POLYPHONY; ++i, ++off)
  63. if(np.ndesc[i].status == 0)
  64. break;
  65. _end = np.ndesc+off;
  66. }
  67. const NoteDescriptor *begin() const {return np.ndesc;};
  68. const NoteDescriptor *end() const { return _end; };
  69. const NoteDescriptor *_end;
  70. const NotePool &np;
  71. };
  72. activeNotesIter activeNotes(NoteDescriptor &n);
  73. activeDescIter activeDesc(void);
  74. constActiveDescIter activeDesc(void) const;
  75. NotePool(void);
  76. //Operations
  77. void insertNote(uint8_t note, uint8_t sendto, SynthDescriptor desc, bool legato=false);
  78. void insertLegatoNote(uint8_t note, uint8_t sendto, SynthDescriptor desc);
  79. void upgradeToLegato(void);
  80. void applyLegato(LegatoParams &par);
  81. bool full(void) const;
  82. bool synthFull(int sdesc_count) const;
  83. //Note that isn't KEY_PLAYING or KEY_RELASED_AND_SUSTAINING
  84. bool existsRunningNote(void) const;
  85. int getRunningNotes(void) const;
  86. int enforceKeyLimit(int limit) const;
  87. void releasePlayingNotes(void);
  88. void releaseNote(note_t note);
  89. void release(NoteDescriptor &d);
  90. void killAllNotes(void);
  91. void killNote(note_t note);
  92. void kill(NoteDescriptor &d);
  93. void kill(SynthDescriptor &s);
  94. void cleanup(void);
  95. void dump(void);
  96. };