Remove build warning
[platform/core/uifw/inputdelegator.git] / src / MicEffector.cpp
1 /*
2  * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
3  *
4  * Licensed under the Apache License, Version 2.0 (the License);
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an AS IS BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16
17 #include <string.h>
18 #include <efl_assist.h>
19 #include "MicEffector.h"
20
21 using namespace is::ui;
22
23 /**
24  * animation configuration values
25  *
26  */
27 static size_t start_stop_anim_count = 28;
28 static size_t spectrum_count = SAMPLE_COUNT;
29 static float spectrum_posx = 40.0f;
30
31 static float timeout_s = 1.0f / 60.0f;
32
33 #define MATH_PI (3.141592)
34
35 double cubic_easy_in_out(double index, double start, double end, double duration)
36 {
37         index /= duration/2;
38         if (index < 1)
39                 return end/2*index*index*index + start;
40
41         index -= 2;
42         return end/2*(index*index*index + 2) + start;
43 }
44
45 double cubic_easy_in(double index, double start, double end, double duration)
46 {
47         index /= duration;
48         return end*index*index*index*index*index + start;
49 }
50
51 double cubic_easy_out(double index, double start, double end, double duration)
52 {
53         index /= duration;
54         index--;
55         return end*(index*index*index + 1) + start;
56 }
57
58
59 /**
60  * Constructor
61  *
62  * #1. Create ea_vector handle for drawing effect.
63  *     ( 1 canvas, 1 paint and 45 paths )
64  * #2. Drawing empty frame to avoid broken screen.
65  *
66  */
67
68 MicEffector::MicEffector(Evas_Object *canvas, Evas_Object *layout, IMicEffector& effect)
69         : drawcount(0)
70         , forcestop(false)
71         , started(false)
72         , fake(false)
73         , timer(NULL)
74         , layout(layout)
75         , ieffect(effect)
76 {
77 //      path = ea_vector_path_create();
78 //      paint = ea_vector_paint_create();
79 //      ea_vector_paint_set_style(paint, EA_VECTOR_PAINT_STYLE_STROKE);
80 //      ea_vector_paint_set_line_cap(paint, EA_VECTOR_PAINT_LINE_CAP_ROUND);
81 //      ea_vector_paint_set_line_join(paint, EA_VECTOR_PAINT_LINE_JOIN_ROUND);
82 //      ea_vector_paint_set_line_width(paint, 3.0);
83 //      ea_vector_paint_set_color(paint, 1.0f, 1.0f, 1.0f, 1.0f);
84
85 //      this->canvas = ea_vector_canvas_create(canvas);
86
87         DrawDummyFrame();
88 };
89
90
91
92 /**
93  * Destructor
94  *
95  * #1. Destroy ea_vector handle
96  *
97  */
98 MicEffector::~MicEffector()
99 {
100         if(timer)
101         {
102                 ecore_timer_del(timer);
103                 timer = NULL;
104         }
105
106 //      ea_vector_path_destroy(path);
107 //      ea_vector_paint_destroy(paint);
108 //      ea_vector_canvas_destroy(canvas);
109 }
110
111
112
113 /**
114  * Draw empty frame to remove or initiate screen
115  *
116  */
117 void MicEffector::DrawDummyFrame()
118 {
119 //      ea_vector_path_reset(path);
120 //      ea_vector_path_move_to(path, 0, 0);
121 //      ea_vector_path_line_to(path, 0, 0);
122 //      ea_vector_canvas_draw(canvas, path, paint);
123 }
124
125
126
127 /**
128  * Draw Que animation
129  *
130  * In case of start, it shows 2 more dots per one time.
131  * In case of stop, it remove 2 dots per one time.
132  *
133  * it works during 22 times.
134  *
135  */
136 void MicEffector::DrawQue(int idx, bool is_start)
137 {
138 //      float margin = spectrum_posx;
139 //      float posx = 0.0;
140
141         double speed = cubic_easy_out(idx + 1.0, 0.0, 23.0, 23);
142
143         unsigned int start = start_stop_anim_count - (int) speed;
144         unsigned int end = start_stop_anim_count + (int) speed;
145
146 //      double opacity;
147
148         if (is_start) {
149 //              opacity = cubic_easy_out(idx, 0.0, 1.0, 26.0);
150         } else {
151 //              opacity = cubic_easy_out(idx, 0, 1.0, 26.0);
152         }
153
154 //      ea_vector_path_reset(path);
155
156         for(unsigned int i = start; i < end; i++)
157         {
158 //              posx = margin + (i * 5);
159
160 //              ea_vector_path_move_to(path, posx, 37.0f);
161 //              ea_vector_path_line_to(path, posx, 38.0f);
162
163 //              ea_vector_paint_set_color(paint, 1.0f, 1.0f, 1.0f, opacity);
164         }
165
166 //      ea_vector_canvas_draw(canvas, path, paint);
167 }
168
169
170
171 float MicEffector::GetAmplifyValue(unsigned int idx)
172 {
173         float amplify = 0.0;
174
175         int max[SAMPLE_COUNT] = {
176                 /**
177                  * dot "A" (9)
178                  *
179                  */
180                 1, 1, 1, 1,
181
182
183                 1, 1, 1, 1, 1, 1, 1, 1, 1,
184
185                 /**
186                  * dot "B" (9)
187                  *
188                  */
189                 10, 8, 2, 3, 10, 11, 6, 12, 4,
190
191                 /**
192                  * dot "C" (15)
193                  *
194                  */
195                  3, 5, 9, 12, 11, 8, 14, 15, 13, 11, 12, 6, 8, 3, 2,
196
197                 /**
198                  * reverse dot "B" (9)
199                  *
200                  */
201                  4, 12, 6, 11, 10, 3, 2, 8, 10,
202
203                 /**
204                  * dot "A" (9)
205                  *
206                  */
207                 1, 1, 1, 1, 1, 1, 1, 1, 1,
208
209                 1, 1, 1, 1
210         };
211
212         amplify = (float) max[idx] / 10.0f * 1.9f;
213
214         return amplify;
215 }
216
217 /**
218  * Draw effect animation
219  *
220  * It draws volume effect. during 5 times.
221  * Center of effect area, it applies amplified value.
222  *
223  */
224 void MicEffector::DrawWave(unsigned int idx, int amount, int prev_amount, double opacity, bool is_lastcmd)
225 {
226 //      float ratio = GetAmplifyValue(idx);
227
228 //      float am = ((float) amount) * ratio;
229 //      float pam = ((float) prev_amount) * ratio;
230 //      float cnt = (float) drawcount;
231
232         float posx = spectrum_posx;
233
234 //      float height = pam > am?
235 //              pam - cubic_easy_in_out(cnt + 1.0, am, pam, 7):
236 //              cubic_easy_in_out(cnt + 1.0, pam, am, 7);
237
238         posx += idx * 5;
239
240 //      ea_vector_path_move_to(path, posx, (37.0f - (height / 2.0)));
241 //      ea_vector_path_line_to(path, posx, (38.0f + (height / 2.0)));
242
243         if (is_lastcmd) {
244 //              ea_vector_paint_set_color(paint, 0.1451f, 0.204f, 0.255f, opacity);//RGB = 37:52:65
245         } else {
246 //              ea_vector_paint_set_color(paint, 1.0f, 1.0f, 1.0f, opacity);//RGB: 255 255 255
247         }
248 }
249
250
251
252 /**
253  * Effect Start
254  *
255  */
256 void MicEffector::Start()
257 {
258         if(timer) {
259                 ecore_timer_del(timer);
260                 timer = NULL;
261         }
262
263         drawcount = 0;
264
265         prev.clear();
266         current.clear();
267
268         for(size_t i = 0; i < spectrum_count; i++)
269         {
270                 prev.push_back(0);
271                 current.push_back(0);
272         }
273
274         Listening();
275
276         /**
277          * Que animation
278          *
279          */
280         timer = ecore_timer_add(timeout_s,
281                                 [](void *data)->Eina_Bool
282                                 {
283                                         MicEffector *effector = static_cast<MicEffector*>(data);
284
285                                         effector->DrawQue(effector->drawcount);
286
287                                         if(effector->drawcount < (int) start_stop_anim_count) {
288                                                 effector->drawcount += 2;
289                                                 return ECORE_CALLBACK_RENEW;
290                                         } else {
291                                                 for(unsigned int i = 0; i < spectrum_count; i++)
292                                                         effector->DrawWave(i, 0, 0);
293
294 //                                              ea_vector_canvas_draw(effector->canvas, effector->path, effector->paint);
295
296                                                 effector->drawcount = 0;
297                                                 effector->timer = NULL;
298                                                 effector->VolumeCheck();
299                                                 effector->Effect();
300                                                 return ECORE_CALLBACK_CANCEL;
301                                         }
302                                 },
303                                 this);
304 }
305
306 /**
307  * Volume effect
308  *
309  */
310 void MicEffector::Effect(bool fake)
311 {
312         /**
313          * Volume effect animation
314          *
315          */
316         if ( timer ) {
317                         ecore_timer_del(timer);
318                         timer = NULL;
319         }
320
321         timer = ecore_timer_add(timeout_s,
322                                 [](void *data)->Eina_Bool
323                                 {
324                                         MicEffector *effector = static_cast<MicEffector *>(data);
325
326                                         bool is_empty_prev = effector->prev.empty();
327
328
329 //                                      ea_vector_path_reset(effector->path);
330
331                                         for(unsigned int i = 0; i < effector->current.size(); i++)
332                                         {
333                                                 if (is_empty_prev)
334                                                         effector->DrawWave(i, effector->current.at(i), 0);
335                                                 else
336                                                         effector->DrawWave(i, effector->current.at(i), effector->prev.at(i));
337                                         }
338 //                                      ea_vector_canvas_draw(effector->canvas, effector->path, effector->paint);
339
340                                         if (effector->drawcount < 7)    {
341                                                 effector->drawcount++;
342                                         } else {
343                                                 effector->drawcount = 0;
344                                                 effector->VolumeCheck(effector->fake);
345                                         }
346
347                                         return ECORE_CALLBACK_RENEW;
348                                 }, this);
349 }
350
351
352
353 /**
354  * Stop volume animation effect
355  *
356  */
357 void MicEffector::Stop(bool forced)
358 {
359         if(timer)
360         {
361                 ecore_timer_del(timer);
362                 timer = NULL;
363         }
364
365         if(!started)
366         {
367                 Idle();
368                 return;
369         }
370
371         forcestop = forced;
372
373         timer = ecore_timer_add(timeout_s,
374                 [](void *data)->Eina_Bool
375                 {
376                         MicEffector *effector = static_cast<MicEffector*>(data);
377
378                         effector->DrawQue(start_stop_anim_count - effector->drawcount, false);
379
380                         if(effector->drawcount < (int) start_stop_anim_count) {
381                                 effector->drawcount += 2;
382                                 return ECORE_CALLBACK_RENEW;
383                         } else {
384                                 if(!effector->forcestop) {
385                                         effector->Processing();
386                                 } else {
387                                         effector->Idle();
388                                 }
389
390                                 effector->forcestop = false;
391                                 effector->drawcount = 0;
392                                 effector->timer = NULL;
393                                 return ECORE_CALLBACK_CANCEL;
394                         }
395                 }, this);
396 }
397
398 /**
399  * Signal. Refresh volume effect
400  *
401  */
402 void MicEffector::VolumeCheck(bool fake)
403 {
404         std::vector<int> volumes;
405
406         this->fake = fake;
407
408         if(!fake) {
409                 volumes = ieffect.GetVolume();
410         } else {
411                 for(unsigned int i = 0; i < spectrum_count; i++) {
412                         volumes.push_back(rand_r((unsigned int*)time(NULL)) % 2);
413                 }
414         }
415
416         prev.clear();
417         prev.assign(current.begin(), current.end());
418
419         current.clear();
420         current.assign(volumes.begin(), volumes.end());
421 }
422
423
424
425 /**
426  * Signal. Listening effect
427  *
428  */
429 void MicEffector::Listening()
430 {
431         started = true;
432
433         elm_object_signal_emit(layout, "elm,state,eq,show", "eq");
434         elm_object_signal_emit(layout, "elm,state,listening", "elm");
435 }
436
437
438
439 /**
440  * Signal. Processing effect
441  *
442  */
443 void MicEffector::Processing()
444 {
445         started = false;
446
447         elm_object_signal_emit(layout, "elm,state,eq,hide", "eq");
448         elm_object_signal_emit(layout, "elm,state,processing", "elm");
449
450         ieffect.ProcessingAnimationStart();
451 }
452
453
454
455 /**
456  * Signal. Idle effect
457  *
458  */
459 void MicEffector::Idle()
460 {
461         const char *text;
462         const char *state;
463         double val;
464
465         started = false;
466
467         elm_object_signal_emit(layout, "elm,state,eq,hide", "eq");
468
469         text = elm_object_part_text_get(layout, "elm.text");
470         state = edje_object_part_state_get(elm_layout_edje_get(layout), "guide_text_block", &val);
471
472         if ((text && strlen(text) > 0) && (state && !strcmp(state, "bottom")))
473                 elm_object_signal_emit(layout, "elm,state,init_message", "elm");
474         else
475                 elm_object_signal_emit(layout, "elm,state,init", "elm");
476
477         ieffect.ProcessingAnimationStop();
478 }
479