1 /*
2 * Author: Harry van Haaren 2013
3 * harryhaaren@gmail.com
4 *
5 * This program is free software: you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation, either version 3 of the License, or
8 * (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program. If not, see <http://www.gnu.org/licenses/>.
17 */
18
19 #include "gridlogic.hxx"
20
21 #include "jack.hxx"
22
23 #include "trackoutput.hxx"
24 #include "controllerupdater.hxx"
25
26 extern Jack* jack;
27
28 const char* GridLogic::StateString[8] = {
29 "Empty",
30 "Playing",
31 "Play queued",
32 "Stopped",
33 "Stop queued",
34 "Recording",
35 "Record queued"
36 };
37
GridLogic()38 GridLogic::GridLogic()
39 {
40 sceneLaunch = 0;
41
42 sampleTrackScene = false;
43 selectedTrack = 0;
44 selectedScene = 0;
45 }
46
selectedTrackSceneEvent(bool p)47 void GridLogic::selectedTrackSceneEvent(bool p)
48 {
49 if ( p ) {
50 pressed( selectedTrack, selectedScene );
51 } else {
52 released( selectedTrack, selectedScene );
53 }
54 }
55
setSelectTrackScene(bool b)56 void GridLogic::setSelectTrackScene(bool b)
57 {
58 char tmp[40];
59 sprintf( tmp, "Select track enable %i", int(b) );
60 EventGuiPrint e( tmp );
61 writeToGuiRingbuffer( &e );
62 sampleTrackScene = b;
63 }
64
getLaunchedScene()65 int GridLogic::getLaunchedScene()
66 {
67 return sceneLaunch;
68 }
69
getSelectedTrack()70 int GridLogic::getSelectedTrack()
71 {
72 return selectedTrack;
73 }
74
getSelectedScene()75 int GridLogic::getSelectedScene()
76 {
77 return selectedScene;
78 }
79
setSelectedTrack(int t)80 void GridLogic::setSelectedTrack(int t)
81 {
82 selectedTrack = t;
83 }
84
setSelectedScene(int s)85 void GridLogic::setSelectedScene(int s)
86 {
87 selectedScene = s;
88 }
89
90
launchScene(int scene)91 void GridLogic::launchScene( int scene )
92 {
93 for(unsigned int t = 0; t < NTRACKS; t++ ) {
94 for(int s = 0; s < NSCENES; s++ ) {
95 LooperClip* lc = jack->getLooper( t )->getClip( s );
96 if ( s == scene ) {
97 lc->queuePlay();
98 jack->getControllerUpdater()->setSceneState( t, s, lc->getState() );
99 } else {
100 if ( lc->playing() ) {
101 lc->queueStop();
102 jack->getControllerUpdater()->setSceneState( t, s, lc->getState() );
103 } else if ( lc->somethingQueued() ) {
104 lc->neutralize();
105 jack->getControllerUpdater()->setSceneState( t, s, lc->getState() );
106 }
107 }
108 }
109 }
110
111 sceneLaunch = scene;
112
113 jack->getControllerUpdater()->launchScene( scene );
114 }
115
specialScene(int t,int s)116 void GridLogic::specialScene(int t, int s)
117 {
118 if ( t < 0 ) t = 0;
119 if ( t >= NTRACKS ) t = NTRACKS-1;
120
121 if ( s < 0 ) s = 0;
122 if ( s >= NSCENES ) s = NSCENES-1;
123
124 selectedTrack = t;
125 selectedScene = s;
126
127 // update UI's
128 jack->getControllerUpdater()->specialScene( t, s );
129 }
130
pressed(int track,int scene)131 void GridLogic::pressed( int track, int scene )
132 {
133 if ( sampleTrackScene ) {
134 specialScene( track, scene );
135
136 // don't act on grid press!
137 return;
138 }
139
140
141 // get the clip, do the "press" action based on current state.
142 LooperClip* lc = jack->getLooper( track )->getClip( scene );
143 TrackOutput* to = jack->getTrackOutput( track );
144 GridLogic::State s = lc->getState();
145
146 #ifdef DEBUG_CLIP
147 printf("GridLogic::pressed() before press state = %s\n", StateString[ int(scene) ] );
148 #endif
149
150 if ( to->recordArm() && !lc->recording() ) {
151 lc->queueRecord();
152 to->recordArm(false);
153 jack->getControllerUpdater()->recordArm( track, false );
154 } else {
155 if ( s == STATE_EMPTY )
156 lc->queueRecord();
157
158 if ( s == STATE_STOPPED ) {
159 // hack, stop all scenes, then launch proper one
160 for( int i = 0; i < NTRACKS; i++ ) {
161 LooperClip* ilc = jack->getLooper( track )->getClip( i );
162 if ( ilc->playing() ) {
163 ilc->queueStop();
164 }
165 }
166
167 lc->queuePlay();
168 }
169
170 if ( s == STATE_PLAYING )
171 lc->queueStop();
172
173 if ( s == STATE_RECORDING )
174 lc->queuePlay();
175
176 if ( s == STATE_PLAY_QUEUED )
177 lc->queueStop();
178
179 if ( s == STATE_STOP_QUEUED )
180 lc->queuePlay();
181
182 // don't re-trigger if already playing!
183 if ( s == STATE_STOP_QUEUED && lc->playing() )
184 lc->neutralize();
185
186 if ( s == STATE_RECORD_QUEUED )
187 lc->neutralize();
188 }
189
190 // check state of new clip, if getQueuePlay() == true, queueStop() all other scenes
191 //if ( lc->getQueuePlay() )
192 {
193 for(int i = 0; i < NSCENES; i++) {
194 // exclude current scene
195 if ( i != scene ) {
196 //LUPPP_NOTE("netralizing & qStop on scene %i due to press on %i", i, scene );
197 LooperClip* ilc = jack->getLooper( track )->getClip( i );
198
199 ilc->neutralize();
200 ilc->queueStop();
201 jack->getControllerUpdater()->setSceneState(track, i, ilc->getState() );
202 }
203 }
204 }
205
206
207 s = lc->getState();
208 #ifdef DEBUG_CLIP
209 printf("GridLogic::pressed() after press state = %s\n", StateString[ int(s) ] );
210 #endif
211 jack->getControllerUpdater()->setSceneState(track, scene, s );
212 }
213
clear(int track,int scene)214 void GridLogic::clear( int track, int scene )
215 {
216 jack->getLooper( track )->getClip( scene )->init();
217 jack->getControllerUpdater()->setTrackSceneProgress(track, scene, 0 );
218 jack->getControllerUpdater()->setSceneState( track, scene, GridLogic::STATE_EMPTY );
219 }
220
released(int track,int scene)221 void GridLogic::released( int track, int scene )
222 {
223 GridLogic::State s = jack->getLooper( track )->getClip( scene )->getState();
224 jack->getControllerUpdater()->setSceneState(track, scene, s );
225 }
226
load(int track,int scene,AudioBuffer * ab)227 void GridLogic::load(int track, int scene, AudioBuffer* ab)
228 {
229 jack->getLooper( track )->getClip( scene )->load( ab );
230 GridLogic::State s = jack->getLooper( track )->getClip( scene )->getState();
231 jack->getControllerUpdater()->setSceneState(track, scene, s );
232 }
233
234
updateState()235 void GridLogic::updateState()
236 {
237 //printf("GridLogic::updateState() stub" );
238 for(int t = 0; t < NTRACKS; t++) {
239 for(int s = 0; s < NSCENES; s++) {
240 GridLogic::State st = jack->getLooper( t )->getClip( s )->getState();
241 EventGuiPrint e( GridLogic::StateString[st] );
242 writeToGuiRingbuffer( &e );
243 jack->getControllerUpdater()->setSceneState(t, s, st );
244 }
245 }
246 }
247
bar()248 void GridLogic::bar()
249 {
250 #ifdef DEBUG_CLIP
251 EventGuiPrint e( "GridLogic::bar()" );
252 //writeToGuiRingbuffer( &e );
253 #endif
254
255 /// iterate over all clips, if they're set to QUEUED, set to the next state
256 for( int i = 0; i < NTRACKS*NSCENES; i++ ) {
257 int track = i / NSCENES;
258 int scene = i - track * NSCENES;
259 jack->getLooper( track )->getClip(scene)->bar();
260
261 #ifdef DEBUG_CLIP
262 GridLogic::State s = jack->getLooper( track )->getClip( scene )->getState();
263 if ( s != STATE_EMPTY ) {
264 //printf("%i, %i:after bar() state = %s\n", track, scene, StateString[ int(s) ] );
265 }
266 #endif
267 }
268 }
269
270
beat()271 void GridLogic::beat()
272 {
273
274
275 }
276
277