rt300@8
|
1 //
|
rt300@8
|
2 // SequenceController.h
|
rt300@8
|
3 // riftathon
|
rt300@8
|
4 //
|
rt300@8
|
5 // Created by Robert Tubb on 17/10/2014.
|
rt300@8
|
6 //
|
rt300@8
|
7 //
|
rt300@8
|
8
|
rt300@8
|
9 #ifndef __riftathon__SequenceController__
|
rt300@8
|
10 #define __riftathon__SequenceController__
|
rt300@8
|
11
|
rt300@8
|
12 #include <iostream>
|
rt300@8
|
13 #include "presetManager.h"
|
rt300@8
|
14
|
rt300@13
|
15 #define MAX_TARGETS_IN_SEQUENCE 2
|
rt300@10
|
16 #define MIN_TEMPO 80
|
rt300@10
|
17 #define MAX_TEMPO 200
|
rt300@13
|
18 #define NUM_TEMPO_STEPS 3
|
rt300@10
|
19 #define NUM_PRESETS 16
|
rt300@10
|
20
|
rt300@13
|
21 //===============================================================================
|
rt300@13
|
22
|
rt300@10
|
23
|
rt300@8
|
24 class Sequence{
|
rt300@13
|
25 public:
|
rt300@13
|
26 Sequence(vector<int> si, int t, bool pv){
|
rt300@13
|
27 tempo = t;
|
rt300@13
|
28 presetSequence = si;
|
rt300@13
|
29 isSequencePreview = pv;
|
rt300@13
|
30 curStep = 0;
|
rt300@13
|
31 };
|
rt300@13
|
32 bool moveToNextStep(){
|
rt300@13
|
33 curStep++;
|
rt300@13
|
34
|
rt300@13
|
35 if (curStep >= presetSequence.size()){
|
rt300@13
|
36 return false;
|
rt300@13
|
37 }else{
|
rt300@13
|
38 return true;
|
rt300@13
|
39 }
|
rt300@13
|
40 };
|
rt300@13
|
41 int getCurrentPresetIndex(){
|
rt300@13
|
42 cout << "step : " << curStep << endl;
|
rt300@13
|
43 if (curStep >= presetSequence.size()){
|
rt300@13
|
44 cout << "ERROR: off end of seq" << endl;
|
rt300@13
|
45 return 0;
|
rt300@13
|
46 }
|
rt300@13
|
47 int i = presetSequence[curStep];
|
rt300@13
|
48 if(i < 0){
|
rt300@13
|
49 cout << "ERROR: negative index" << endl;
|
rt300@13
|
50 }
|
rt300@13
|
51 return i;
|
rt300@13
|
52
|
rt300@13
|
53 };
|
rt300@13
|
54 int getStepNo(){
|
rt300@13
|
55 return curStep;
|
rt300@13
|
56 }
|
rt300@13
|
57 float tempo;
|
rt300@8
|
58
|
rt300@13
|
59 bool isSequencePreview; // true if demoing the seq to the user, false if user is matching a seq
|
rt300@13
|
60 vector<int> presetSequence;
|
rt300@13
|
61 int curStep;
|
rt300@8
|
62
|
rt300@8
|
63 };
|
rt300@8
|
64
|
rt300@13
|
65 //===============================================================================
|
rt300@13
|
66
|
rt300@13
|
67 class Run{
|
rt300@13
|
68 public:
|
rt300@13
|
69 Run(vector<Sequence> vs, int sl){
|
rt300@13
|
70 theSequences = vs;
|
rt300@13
|
71 sequenceLength = sl;
|
rt300@13
|
72 curSeq = 0;
|
rt300@13
|
73 };
|
rt300@13
|
74 bool moveToNextStep(){
|
rt300@13
|
75 if (curSeq >= theSequences.size()){
|
rt300@13
|
76 return false;
|
rt300@13
|
77 }
|
rt300@13
|
78
|
rt300@13
|
79 bool stepFound = theSequences[curSeq].moveToNextStep();
|
rt300@13
|
80 if (stepFound){
|
rt300@13
|
81 return true;
|
rt300@13
|
82 }else{
|
rt300@13
|
83 curSeq++;
|
rt300@13
|
84 if (curSeq >= theSequences.size()){
|
rt300@13
|
85 return false;
|
rt300@13
|
86
|
rt300@13
|
87 }else{
|
rt300@13
|
88 return true;
|
rt300@13
|
89 }
|
rt300@13
|
90 }
|
rt300@13
|
91
|
rt300@13
|
92 return false;
|
rt300@13
|
93 };
|
rt300@13
|
94 int getCurrentPresetIndex(){
|
rt300@13
|
95 cout << "seq : " << curSeq << endl;
|
rt300@13
|
96 if (curSeq >= theSequences.size()){
|
rt300@13
|
97 cout << "ERROR: get preset" << endl;
|
rt300@13
|
98 return 0;
|
rt300@13
|
99 }
|
rt300@13
|
100 return theSequences[curSeq].getCurrentPresetIndex();
|
rt300@13
|
101
|
rt300@13
|
102 };
|
rt300@13
|
103 int getSequenceNo(){
|
rt300@13
|
104 return curSeq;
|
rt300@13
|
105 }
|
rt300@13
|
106
|
rt300@13
|
107 vector<Sequence> theSequences;
|
rt300@13
|
108 int curSeq;
|
rt300@13
|
109 int sequenceLength;
|
rt300@13
|
110
|
rt300@13
|
111 };
|
rt300@13
|
112 //===============================================================================
|
rt300@13
|
113
|
rt300@10
|
114 class SequenceController{
|
rt300@10
|
115 public:
|
rt300@13
|
116
|
rt300@10
|
117 SequenceController(){
|
rt300@10
|
118 makeSequences();
|
rt300@13
|
119 tempoInc = float(MAX_TEMPO - MIN_TEMPO) / float(NUM_TEMPO_STEPS);
|
rt300@13
|
120 curRun = 0;
|
rt300@10
|
121 };
|
rt300@13
|
122
|
rt300@13
|
123 int stepForward(){
|
rt300@13
|
124 cout << "run : " << curRun << endl;
|
rt300@13
|
125 if (curRun >= theRuns.size()){
|
rt300@13
|
126 return -1;
|
rt300@13
|
127 }
|
rt300@13
|
128
|
rt300@13
|
129 bool stepFound = theRuns[curRun].moveToNextStep();
|
rt300@13
|
130 if (stepFound){
|
rt300@13
|
131 return curRun;
|
rt300@13
|
132 }else{
|
rt300@13
|
133 curRun++;
|
rt300@13
|
134 if (curRun >= theRuns.size()){
|
rt300@13
|
135 cout << " END OF RUNS " << endl;
|
rt300@13
|
136 return -1;
|
rt300@13
|
137
|
rt300@13
|
138 }else{
|
rt300@13
|
139 return -2; // in order to stop the metro, next tick will just start thjings agaaain
|
rt300@13
|
140 }
|
rt300@13
|
141 }
|
rt300@10
|
142
|
rt300@13
|
143 return false;
|
rt300@13
|
144
|
rt300@13
|
145 }
|
rt300@13
|
146
|
rt300@13
|
147 int getCurrentPresetIndex(){
|
rt300@10
|
148
|
rt300@10
|
149 // if end of sequence return something else so we can do something
|
rt300@10
|
150 // if end of tempo ramp return something else
|
rt300@13
|
151 if (curRun >= theRuns.size()){
|
rt300@13
|
152 cout << "DAAAAHHH" << endl;
|
rt300@13
|
153 return -1;
|
rt300@13
|
154 }
|
rt300@13
|
155 int nextIndex = theRuns[curRun].getCurrentPresetIndex();
|
rt300@13
|
156
|
rt300@13
|
157 return nextIndex;
|
rt300@13
|
158 };
|
rt300@13
|
159 vector<int> getCurrentRunSeqAndStep(){
|
rt300@13
|
160 vector<int> rss;
|
rt300@13
|
161 // int r = curRun - theRuns.begin();
|
rt300@13
|
162 // int sq = (*curRun).getSequenceNo();
|
rt300@13
|
163 // int s = 4534534;
|
rt300@13
|
164 // rss.push_back(r);
|
rt300@13
|
165 // rss.push_back(sq);
|
rt300@13
|
166 // rss.push_back(s);
|
rt300@13
|
167 return rss;
|
rt300@10
|
168
|
rt300@13
|
169 }
|
rt300@10
|
170 protected:
|
rt300@10
|
171 void makeSequences(){
|
rt300@13
|
172 srand (time(NULL));
|
rt300@10
|
173
|
rt300@13
|
174
|
rt300@13
|
175 for(int numInSequence = 1; numInSequence <= MAX_TARGETS_IN_SEQUENCE; numInSequence++){
|
rt300@13
|
176 float curTempo = MIN_TEMPO;
|
rt300@13
|
177 vector<Sequence> seqsForRun;
|
rt300@13
|
178
|
rt300@10
|
179 for(int tempoLevel = 0; tempoLevel < NUM_TEMPO_STEPS; tempoLevel++){
|
rt300@10
|
180
|
rt300@13
|
181 vector<int> stepsForSequence;
|
rt300@10
|
182
|
rt300@10
|
183 // repeat the same tests for xtra practice?
|
rt300@10
|
184 for(int n=0; n < numInSequence; n++){
|
rt300@13
|
185 int next = getRandomButNot(NUM_PRESETS,stepsForSequence);
|
rt300@13
|
186 stepsForSequence.push_back(next);
|
rt300@10
|
187
|
rt300@10
|
188 cout << next << ",";
|
rt300@10
|
189 }
|
rt300@13
|
190 seqsForRun.push_back(Sequence(stepsForSequence, curTempo, true));
|
rt300@13
|
191 seqsForRun.push_back(Sequence(stepsForSequence, curTempo, false));
|
rt300@13
|
192 curTempo += tempoInc;
|
rt300@10
|
193 cout << endl;
|
rt300@13
|
194
|
rt300@10
|
195 }
|
rt300@13
|
196
|
rt300@13
|
197 theRuns.push_back( Run(seqsForRun,numInSequence) );
|
rt300@13
|
198
|
rt300@10
|
199 cout << "---" << endl;
|
rt300@10
|
200 }
|
rt300@10
|
201 };
|
rt300@8
|
202
|
rt300@10
|
203 int getRandomButNot(int max, vector<int> notThese){
|
rt300@10
|
204
|
rt300@10
|
205 bool there = true;
|
rt300@13
|
206 int randomInt = rand() % max;
|
rt300@10
|
207
|
rt300@10
|
208 if (notThese.size()){
|
rt300@10
|
209 while(there){
|
rt300@10
|
210 randomInt = rand() % max;
|
rt300@10
|
211 vector<int>::iterator result = std::find(notThese.begin(), notThese.end(), randomInt);
|
rt300@10
|
212 there = (result != notThese.end());
|
rt300@10
|
213 }
|
rt300@10
|
214 }
|
rt300@10
|
215 return randomInt;
|
rt300@10
|
216
|
rt300@10
|
217 };
|
rt300@13
|
218
|
rt300@8
|
219
|
rt300@8
|
220 private:
|
rt300@13
|
221
|
rt300@13
|
222 vector<Run> theRuns;
|
rt300@13
|
223 int curRun;
|
rt300@13
|
224
|
rt300@13
|
225 float tempoInc;
|
rt300@8
|
226 };
|
rt300@13
|
227 //===============================================================================
|
rt300@8
|
228
|
rt300@8
|
229 #endif /* defined(__riftathon__SequenceController__) */
|