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 "INPUT_DELEGATOR"
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)
86 vg = evas_object_vg_add(evas_object_evas_get(canvas));
89 root = evas_object_vg_root_node_get(vg);
90 shape = evas_vg_shape_add(root);
91 evas_vg_node_color_set(shape, 80, 80, 80, 80);
93 elm_object_part_content_set(layout, "EFFECT_BG", vg);
95 evas_vg_shape_stroke_cap_set(shape, EFL_GFX_CAP_BUTT);
96 evas_vg_shape_stroke_join_set(shape, EFL_GFX_JOIN_MITER);
98 evas_vg_shape_stroke_width_set(shape, 3.0);
99 evas_vg_shape_stroke_color_set(shape, 255, 255, 255, 255);
107 * #1. Destroy ea_vector handle
110 MicEffector::~MicEffector()
113 ecore_timer_del(timer);
120 evas_object_del(root);
123 evas_object_del(shape);
127 * Draw empty frame to remove or initiate screen
130 void MicEffector::DrawDummyFrame()
132 evas_vg_shape_reset(shape);
133 evas_vg_shape_append_move_to(shape, 0, 0);
134 evas_vg_shape_append_line_to(shape, 0, 0);
136 evas_object_show(vg);
142 * In case of start, it shows 2 more dots per one time.
143 * In case of stop, it remove 2 dots per one time.
145 * it works during 22 times.
148 void MicEffector::DrawQue(int idx, bool is_start)
150 float margin = spectrum_posx;
153 double speed = cubic_easy_out(idx + 1.0, 0.0, 23.0, 23);
155 unsigned int start = start_stop_anim_count - (int) speed;
156 unsigned int end = start_stop_anim_count + (int) speed;
158 double opacity = 0.0;;
161 opacity = cubic_easy_out(idx, 0.0, 1.0, 26.0);
163 opacity = cubic_easy_out(idx, 0, 1.0, 26.0);
166 evas_vg_shape_reset(shape);
168 for (unsigned int i = start; i < end; i++)
170 posx = margin + (i * 5);
172 evas_vg_shape_append_move_to(shape, posx, 37);
173 evas_vg_shape_append_line_to(shape, posx, 38);
174 evas_vg_shape_stroke_color_set(shape, 255, 255, 255, opacity);
177 evas_object_show(vg);
180 float MicEffector::GetAmplifyValue(unsigned int idx)
184 int max[SAMPLE_COUNT] = {
192 1, 1, 1, 1, 1, 1, 1, 1, 1,
198 10, 8, 2, 3, 10, 11, 6, 12, 4,
204 3, 5, 9, 12, 11, 8, 14, 15, 13, 11, 12, 6, 8, 3, 2,
207 * reverse dot "B" (9)
210 4, 12, 6, 11, 10, 3, 2, 8, 10,
216 1, 1, 1, 1, 1, 1, 1, 1, 1,
221 amplify = (float) max[idx] / 10.0f * 1.9f;
227 * Draw effect animation
229 * It draws volume effect. during 5 times.
230 * Center of effect area, it applies amplified value.
233 void MicEffector::DrawWave(unsigned int idx, int amount, int prev_amount, double opacity, bool is_lastcmd)
235 float ratio = GetAmplifyValue(idx);
237 float am = ((float) amount) * ratio;
238 float pam = ((float) prev_amount) * ratio;
239 float cnt = (float) drawcount;
241 float posx = spectrum_posx;
243 float height = pam > am?
244 pam - cubic_easy_in_out(cnt + 1.0, am, pam, 7):
245 cubic_easy_in_out(cnt + 1.0, pam, am, 7);
249 evas_vg_shape_append_move_to(shape, posx, (37.0f - (height / 2.0)));
250 evas_vg_shape_append_line_to(shape, posx, (38.0f + (height / 2.0)));
251 evas_vg_shape_stroke_color_set(shape, 255, 255, 255, opacity);
258 void MicEffector::Start()
261 ecore_timer_del(timer);
270 for (size_t i = 0; i < spectrum_count; i++)
273 current.push_back(0);
282 timer = ecore_timer_add(timeout_s,
283 [](void *data)->Eina_Bool
285 MicEffector *effector = static_cast<MicEffector*>(data);
287 effector->DrawQue(effector->drawcount);
289 if (effector->drawcount < (int) start_stop_anim_count) {
290 effector->drawcount += 2;
291 return ECORE_CALLBACK_RENEW;
293 for (unsigned int i = 0; i < spectrum_count; i++)
294 effector->DrawWave(i, 0, 0);
296 evas_object_show(effector->vg);
298 effector->drawcount = 0;
299 effector->timer = NULL;
300 effector->VolumeCheck(true);
302 return ECORE_CALLBACK_CANCEL;
312 void MicEffector::Effect(bool fake)
315 * Volume effect animation
319 ecore_timer_del(timer);
323 timer = ecore_timer_add(timeout_s,
324 [](void *data)->Eina_Bool
326 MicEffector *effector = static_cast<MicEffector *>(data);
328 bool is_empty_prev = effector->prev.empty();
330 evas_vg_shape_reset(effector->shape);
332 for (unsigned int i = 0; i < effector->current.size(); i++)
335 effector->DrawWave(i, effector->current.at(i), 0);
337 effector->DrawWave(i, effector->current.at(i), effector->prev.at(i));
340 evas_object_show(effector->vg);
342 if (effector->drawcount < 7) {
343 effector->drawcount++;
344 effector->VolumeCheck(true);
346 effector->drawcount = 0;
347 effector->VolumeCheck(true);
350 return ECORE_CALLBACK_RENEW;
355 * Stop volume animation effect
358 void MicEffector::Stop(bool forced)
362 ecore_timer_del(timer);
374 timer = ecore_timer_add(timeout_s,
375 [](void *data)->Eina_Bool
377 MicEffector *effector = static_cast<MicEffector*>(data);
379 effector->DrawQue(start_stop_anim_count - effector->drawcount, false);
381 if (effector->drawcount < (int) start_stop_anim_count) {
382 effector->drawcount += 2;
383 return ECORE_CALLBACK_RENEW;
385 effector->forcestop = false;
386 effector->drawcount = 0;
387 effector->timer = NULL;
388 return ECORE_CALLBACK_CANCEL;
394 * Signal. Refresh volume effect
397 void MicEffector::VolumeCheck(bool fake)
399 std::vector<int> volumes;
404 volumes = ieffect.GetVolume();
406 for (unsigned int i = 0; i < spectrum_count; i++) {
407 unsigned int seed = time(NULL);
408 volumes.push_back(rand_r(&seed) % 6);
413 prev.assign(current.begin(), current.end());
416 current.assign(volumes.begin(), volumes.end());
420 * Signal. Listening effect
423 void MicEffector::Listening()
427 elm_object_signal_emit(layout, "elm,state,listening", "elm");
428 elm_object_signal_emit(layout, "elm,state,eq,show", "eq");
432 * Signal. Processing effect
435 void MicEffector::Processing()
439 elm_object_signal_emit(layout, "elm,state,eq,hide", "eq");
440 elm_object_signal_emit(layout, "elm,state,processing", "elm");
442 ieffect.ProcessingAnimationStart();
446 * Signal. Idle effect
449 void MicEffector::Idle()
457 elm_object_signal_emit(layout, "elm,state,eq,hide", "eq");
459 text = elm_object_part_text_get(layout, "elm.text");
460 state = edje_object_part_state_get(elm_layout_edje_get(layout), "guide_text_block", &val);
462 if ((text && strlen(text) > 0) && (state && !strcmp(state, "bottom")))
463 elm_object_signal_emit(layout, "elm,state,init_message", "elm");
465 elm_object_signal_emit(layout, "elm,state,init", "elm");
467 ieffect.ProcessingAnimationStop();