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.

114 lines
2.8KB

  1. #ifndef GENERATIVETRIGGERGENERATOR
  2. #define GENERATIVETRIGGERGENERATOR
  3. #include "StochasticGrammar.h"
  4. #include "TriggerSequencer.h"
  5. /* Knows how to generate trigger sequence data
  6. * when evaluating a grammar
  7. */
  8. class GTGEvaluator : public ProductionRule::EvaluationState
  9. {
  10. public:
  11. GTGEvaluator(AudioMath::RandomUniformFunc xr, TriggerSequencer::Event * buf) :
  12. ProductionRule::EvaluationState(xr),
  13. _buf(buf),
  14. _delay(0)
  15. {
  16. }
  17. void writeSymbol(GKEY key) override
  18. {
  19. // first: write out a trigger at "current delay"
  20. _buf->evt = TriggerSequencer::TRIGGER;
  21. _buf->delay = _delay;
  22. ++_buf;
  23. // then set current dealy to duration of key
  24. _delay = ProductionRuleKeys::getDuration(key);
  25. }
  26. // call this to write final event
  27. void writeEnd()
  28. {
  29. _buf->evt = TriggerSequencer::END;
  30. _buf->delay = _delay;
  31. }
  32. private:
  33. TriggerSequencer::Event * _buf;
  34. int _delay;
  35. };
  36. /* wraps up some stochastic gnerative grammar stuff feeding
  37. * a trigger sequencer
  38. */
  39. class GenerativeTriggerGenerator
  40. {
  41. public:
  42. GenerativeTriggerGenerator(AudioMath::RandomUniformFunc r, const ProductionRule * rules, int numRules, GKEY initialState) :
  43. _r(r),
  44. _rules(rules),
  45. _numRules(numRules),
  46. _initKey(initialState)
  47. {
  48. _data[0].delay = 0;
  49. _data[0].evt = TriggerSequencer::END;
  50. _seq = new TriggerSequencer(_data);
  51. }
  52. ~GenerativeTriggerGenerator()
  53. {
  54. delete _seq;
  55. }
  56. void setGrammar(const ProductionRule * rules, int numRules, GKEY initialState)
  57. {
  58. _rules = rules;
  59. _numRules = numRules;
  60. _initKey = initialState;
  61. }
  62. // returns true if trigger generated
  63. bool clock()
  64. {
  65. _seq->clock();
  66. bool ret = _seq->getTrigger();
  67. if (_seq->getEnd()) {
  68. // when we finish playing the seq, generate a new random one
  69. generate();
  70. ret |= _seq->getTrigger();
  71. //printf("this should be getTrigger!!!\n");
  72. }
  73. return ret;
  74. }
  75. private:
  76. TriggerSequencer * _seq;
  77. TriggerSequencer::Event _data[33];
  78. AudioMath::RandomUniformFunc _r;
  79. const ProductionRule * _rules;
  80. int _numRules;
  81. GKEY _initKey;
  82. //
  83. void generate()
  84. {
  85. GTGEvaluator es(_r, _data);
  86. es.rules = _rules;
  87. es.numRules = _numRules;
  88. ProductionRule::evaluate(es, _initKey);
  89. es.writeEnd();
  90. TriggerSequencer::isValid(_data);
  91. _seq->reset(_data);
  92. assert(!_seq->getEnd());
  93. #if 0
  94. printf("just generated trigger seq\n");
  95. TriggerSequencer::Event * p;
  96. for (p = _data; p->evt != TriggerSequencer::END; ++p) {
  97. printf("evt=%d, delay=%d\n", p->evt, p->delay);
  98. }
  99. printf("delay to end = %d\n", p->delay);
  100. #endif
  101. }
  102. };
  103. #endif