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.

152 lines
4.4KB

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