2 * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
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
8 * http://www.apache.org/licenses/LICENSE-2.0
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.
17 #define EFL_BETA_API_SUPPORT 1
18 #define EFL_EO_API_SUPPORT 1
23 #include "MicEffector.h"
25 #include <Elementary.h>
29 #define LOG_TAG "ISE_DEFAULT"
32 using namespace is::ui;
35 * animation configuration values
38 static size_t start_stop_anim_count = 28;
39 static size_t spectrum_count = SAMPLE_COUNT;
40 static float spectrum_posx = 40.0f;
42 static float timeout_s = 1.0f / 60.0f;
44 #define MATH_PI (3.141592)
46 double cubic_easy_in_out(double index, double start, double end, double duration)
50 return end/2*index*index*index + start;
53 return end/2*(index*index*index + 2) + start;
56 double cubic_easy_in(double index, double start, double end, double duration)
59 return end*index*index*index*index*index + start;
62 double cubic_easy_out(double index, double start, double end, double duration)
66 return end*(index*index*index + 1) + start;
72 * #1. Create ea_vector handle for drawing effect.
73 * ( 1 canvas, 1 paint and 45 paths )
74 * #2. Drawing empty frame to avoid broken screen.
77 MicEffector::MicEffector(Evas_Object *canvas, Evas_Object *layout, IMicEffector& effect)
89 vg = evas_object_vg_add(evas_object_evas_get(canvas));
90 /* temporary code to avoid crash when evas_vg_shape_add is crash sometimes */
97 root = evas_object_vg_root_node_get(vg);
98 /* temporary code to avoid crash when evas_vg_shape_add is crash sometimes */
100 LOGW("root is null");
104 shape = evas_vg_shape_add(root);
105 evas_vg_node_color_set(shape, 80, 80, 80, 80);
107 elm_object_part_content_set(layout, "EFFECT_BG", vg);
109 evas_vg_shape_stroke_cap_set(shape, EVAS_VG_CAP_BUTT);
110 evas_vg_shape_stroke_join_set(shape, EVAS_VG_JOIN_MITER);
112 evas_vg_shape_stroke_width_set(shape, 3.0);
114 evas_vg_shape_stroke_color_set(shape, 255, 255, 255, 255);
116 evas_vg_shape_stroke_color_set(shape, 51, 204, 255, 255);
124 * #1. Destroy ea_vector handle
127 MicEffector::~MicEffector()
130 ecore_timer_del(timer);
137 evas_object_del(root);
140 evas_object_del(shape);
144 * Draw empty frame to remove or initiate screen
147 void MicEffector::DrawDummyFrame()
149 evas_vg_shape_reset(shape);
150 evas_vg_shape_append_move_to(shape, 0, 0);
151 evas_vg_shape_append_line_to(shape, 0, 0);
153 evas_object_show(vg);
159 * In case of start, it shows 2 more dots per one time.
160 * In case of stop, it remove 2 dots per one time.
162 * it works during 22 times.
165 void MicEffector::DrawQue(int idx, bool is_start)
167 float margin = spectrum_posx;
170 double speed = cubic_easy_out(idx + 1.0, 0.0, 23.0, 23);
172 unsigned int start = start_stop_anim_count - (int) speed;
173 unsigned int end = start_stop_anim_count + (int) speed;
179 opacity = cubic_easy_out(idx, 0.0, 1.0, 26.0);
181 opacity = cubic_easy_out(idx, 0, 1.0, 26.0);
185 evas_vg_shape_reset(shape);
187 for (unsigned int i = start; i < end; i++)
189 posx = margin + (i * 5);
191 evas_vg_shape_append_move_to(shape, posx, 37);
192 evas_vg_shape_append_line_to(shape, posx, 38);
194 evas_vg_shape_stroke_color_set(shape, 255, 255, 255, opacity);
196 evas_vg_shape_stroke_color_set(shape, 51, 204, 255, 255);
200 evas_object_show(vg);
203 float MicEffector::GetAmplifyValue(unsigned int idx)
207 int max[SAMPLE_COUNT] = {
215 1, 1, 1, 1, 1, 1, 1, 1, 1,
221 10, 8, 2, 3, 10, 11, 6, 12, 4,
227 3, 5, 9, 12, 11, 8, 14, 15, 13, 11, 12, 6, 8, 3, 2,
230 * reverse dot "B" (9)
233 4, 12, 6, 11, 10, 3, 2, 8, 10,
239 1, 1, 1, 1, 1, 1, 1, 1, 1,
244 amplify = (float) max[idx] / 10.0f * 1.9f;
250 * Draw effect animation
252 * It draws volume effect. during 5 times.
253 * Center of effect area, it applies amplified value.
256 void MicEffector::DrawWave(unsigned int idx, int amount, int prev_amount, double opacity, bool is_lastcmd)
258 float ratio = GetAmplifyValue(idx);
260 float am = ((float) amount) * ratio;
261 float pam = ((float) prev_amount) * ratio;
262 float cnt = (float) drawcount;
264 float posx = spectrum_posx;
266 float height = pam > am?
267 pam - cubic_easy_in_out(cnt + 1.0, am, pam, 7):
268 cubic_easy_in_out(cnt + 1.0, pam, am, 7);
272 evas_vg_shape_append_move_to(shape, posx, (37.0f - (height / 2.0)));
273 evas_vg_shape_append_line_to(shape, posx, (38.0f + (height / 2.0)));
276 evas_vg_shape_stroke_color_set(shape, 255, 255, 255, opacity);
278 evas_vg_shape_stroke_color_set(shape, 51, 204, 255, 255);
286 void MicEffector::Start()
289 ecore_timer_del(timer);
298 for (size_t i = 0; i < spectrum_count; i++)
301 current.push_back(0);
310 timer = ecore_timer_add(timeout_s,
311 [](void *data)->Eina_Bool
313 MicEffector *effector = static_cast<MicEffector*>(data);
315 effector->DrawQue(effector->drawcount);
317 if (effector->drawcount < (int) start_stop_anim_count) {
318 effector->drawcount += 2;
319 return ECORE_CALLBACK_RENEW;
321 for (unsigned int i = 0; i < spectrum_count; i++)
322 effector->DrawWave(i, 0, 0);
324 evas_object_show(effector->vg);
326 effector->drawcount = 0;
327 effector->timer = NULL;
328 effector->VolumeCheck(true);
330 return ECORE_CALLBACK_CANCEL;
340 void MicEffector::Effect(bool fake)
343 * Volume effect animation
347 ecore_timer_del(timer);
351 timer = ecore_timer_add(timeout_s,
352 [](void *data)->Eina_Bool
354 MicEffector *effector = static_cast<MicEffector *>(data);
356 bool is_empty_prev = effector->prev.empty();
358 evas_vg_shape_reset(effector->shape);
360 for (unsigned int i = 0; i < effector->current.size(); i++)
363 effector->DrawWave(i, effector->current.at(i), 0);
365 effector->DrawWave(i, effector->current.at(i), effector->prev.at(i));
368 evas_object_show(effector->vg);
370 if (effector->drawcount < 7) {
371 effector->drawcount++;
372 effector->VolumeCheck(true);
374 effector->drawcount = 0;
375 effector->VolumeCheck(true);
378 return ECORE_CALLBACK_RENEW;
383 * Stop volume animation effect
386 void MicEffector::Stop(bool forced)
390 ecore_timer_del(timer);
402 timer = ecore_timer_add(timeout_s,
403 [](void *data)->Eina_Bool
405 MicEffector *effector = static_cast<MicEffector*>(data);
407 effector->DrawQue(start_stop_anim_count - effector->drawcount, false);
409 if (effector->drawcount < (int) start_stop_anim_count) {
410 effector->drawcount += 2;
411 return ECORE_CALLBACK_RENEW;
413 if (!effector->forcestop) {
414 // effector->Processing();
416 #if defined(_MOBILE) || defined(_COMMON)
421 effector->forcestop = false;
422 effector->drawcount = 0;
423 effector->timer = NULL;
424 return ECORE_CALLBACK_CANCEL;
430 * Signal. Refresh volume effect
433 void MicEffector::VolumeCheck(bool fake)
435 std::vector<int> volumes;
440 volumes = ieffect.GetVolume();
442 for (unsigned int i = 0; i < spectrum_count; i++) {
443 unsigned int seed = time(NULL);
445 volumes.push_back(rand_r(&seed) % 6);
447 volumes.push_back(rand_r(&seed) % 15);
453 prev.assign(current.begin(), current.end());
456 current.assign(volumes.begin(), volumes.end());
460 * Signal. Listening effect
463 void MicEffector::Listening()
467 elm_object_signal_emit(layout, "elm,state,listening", "elm");
468 elm_object_signal_emit(layout, "elm,state,eq,show", "eq");
472 * Signal. Processing effect
475 void MicEffector::Processing()
479 elm_object_signal_emit(layout, "elm,state,eq,hide", "eq");
480 elm_object_signal_emit(layout, "elm,state,processing", "elm");
482 ieffect.ProcessingAnimationStart();
486 * Signal. Idle effect
489 void MicEffector::Idle()
497 elm_object_signal_emit(layout, "elm,state,eq,hide", "eq");
499 text = elm_object_part_text_get(layout, "elm.text");
500 state = edje_object_part_state_get(elm_layout_edje_get(layout), "guide_text_block", &val);
502 if ((text && strlen(text) > 0) && (state && !strcmp(state, "bottom")))
503 elm_object_signal_emit(layout, "elm,state,init_message", "elm");
505 elm_object_signal_emit(layout, "elm,state,init", "elm");
507 ieffect.ProcessingAnimationStop();