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.

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